diff --git a/ChangeLog.stable b/ChangeLog.stable index 5644456..6a206a3 100644 --- a/ChangeLog.stable +++ b/ChangeLog.stable @@ -4,9 +4,65 @@ WANPIPE Linux Voice TDM/WAN Router Package ------------------------------------------------------------------------------ Author: Nenad Corbic -Copyright (c) 1995-2007 Sangoma Technologies Inc. +Copyright (c) 1995-2008 Sangoma Technologies Inc. ------------------------------------------------------------------------------ +* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.2 +======================================================================== + +- AFT Maxim Front end update + Implemented graceful recovery on short circuit. + +- AFT Driver update + Added a check for TDM IRQ timeout. + On some machines its possible for TDM IRQ to timeout. + +- SMG updated + Fixed wancfg_smg + MTU not properly set on ports 2 and up + Voice only ports were not being added to startup sequence + Updated for callweaver + +- Added Zaptel 1.4 HW HDLC Support + No Sangoma zaptel patch needed with Zaptel 1.4 + +- Added HWEC Noise flag in wanpipe config file + +- Updated SMG +- Updated E1 Unframed on Maxim Cards + +- Updates for AFT PMC and MAXIM framers + PMC - lowered LOS sensitivity + Fixes fake up/down state changes on + started inactive lines. + + MAXIM - lowered sensistivy + Fixes cable cross talk on 8 port cards. + - Enabled Unframed E1 + - Enabled Tri-State Mode + - Fixed loopback commands + +- Fixed HWEC_PERSIST_DISABLE + This option was broken in previous release + This option lets Asterisk control HWEC + on each call start/stop. + By default all hwec channels are enabled on + device startup. + +- Updated SMG/SS7 +- Updated loopback commands for AFT Maxim cards + +- Updated for AstLinux + The make file can now build all WAN and Voice Protocols + +- Fixed add_timer warnings for ALL AFT cards + Caused when a port is left in unconnected state. + +- Updated legacy protocols for new front end architecture + +- Updated Setup script + + * Wed Oct 6 2007 Nenad Corbic - Stable - 3.2.1 ===================================================================== diff --git a/Makefile b/Makefile index f4ba6e9..767947f 100644 --- a/Makefile +++ b/Makefile @@ -59,19 +59,25 @@ EXTRA_UTIL_FLAGS = -I$(PWD)/$(WINCLUDE) -I$(KDIR)/include/ -I$(INSTALLPREFIX)/in EXTRA_UTIL_FLAGS += -I$(PWD)/patches/kdrivers/wanec -I$(PWD)/patches/kdrivers/wanec/oct6100_api/include ENABLE_WANPIPEMON_ZAP=NO +ZAPHDLC_PRIV=/etc/wanpipe/.zaphdlc + +RM = @rm -rf +JUNK = *~ *.bak DEADJOE #Check if zaptel exists ifneq (,$(wildcard $(ZAPDIR)/zaptel.h)) ZAPDIR_PRIV=$(ZAPDIR) ENABLE_WANPIPEMON_ZAP=YES EXTRA_CFLGS+= -DSTANDALONE_ZAPATA -DBUILDING_TONEZONE + ZAP_OPTS= --zaptel-path=$(ZAPDIR) + ZAP_PROT=TDM else + ZAP_OPTS= + ZAP_PROT= ZAPDIR_PRIV= ENABLE_WANPIPEMON_ZAP=NO endif -RM = @rm -rf -JUNK = *~ *.bak DEADJOE # First pass, kernel Makefile reads module objects @@ -83,11 +89,25 @@ else #This will check for zaptel, kenrel source and build utilites and kernel modules #within local directory structure -all: _checkzap _checksrc all_util all_kmod + +#Build with all binaries +all: _checkzap _checksrc all_bin_kmod all_util + +#Build only source (NO WAN protocols) +all_src: _checkzap _checksrc all_kmod all_util + #Build only kernel modules all_kmod: _checkzap _checksrc _cleanoldwanpipe _check_kver - $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C $(KDIR) SUBDIRS=$(WAN_DIR) EXTRA_FLAGS="$(EXTRA_CFLAGS) $(shell cat ./patches/kfeatures)" ZAPDIR=$(ZAPDIR_PRIV) HOMEDIR=$(PWD) modules + $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C $(KDIR) SUBDIRS=$(WAN_DIR) EXTRA_FLAGS="$(EXTRA_CFLAGS) $(shell cat ./patches/kfeatures)" ZAPDIR=$(ZAPDIR_PRIV) ZAPHDLC=$(ZAPHDLC_PRIV) HOMEDIR=$(PWD) modules + +all_bin_kmod: _checkzap _checksrc _cleanoldwanpipe _check_kver + @if [ -e $(PWD)/ast_build_dir ]; then \ + rm -rf $(PWD)/ast_build_dir; \ + fi + @mkdir -p $(PWD)/ast_build_dir + ./Setup drivers --builddir=$(PWD)/ast_build_dir --with-linux=$(KDIR) $(ZAP_OPTS) --usr-cc=$(CC) --protocol=DEF-$(ZAP_PROT) --no-zaptel-compile --noautostart --arch=$(ARCH) --silent + @eval "./patches/copy_modules.sh $(PWD)/ast_build_dir $(WAN_DIR)" #Clean utilites and kernel modules @@ -163,11 +183,13 @@ install_kmod: install -m 644 -D $(WAN_DIR)/sdladrv.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/sdladrv.${MODTYPE} install -m 644 -D $(WAN_DIR)/wanpipe.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe.${MODTYPE} @rm -f $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe_syncppp.${MODTYPE} - @if [ -f $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} ]; then \ + @if [ -e $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} ]; then \ + echo "install -m 644 -D $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe_syncppp.${MODTYPE}"; \ install -m 644 -D $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe_syncppp.${MODTYPE}; \ fi @rm -f $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanpipe_lip.${MODTYPE}; - @if [ -f $(WAN_DIR)/wanpipe_lip.${MODTYPE} ]; then \ + @if [ -e $(WAN_DIR)/wanpipe_lip.${MODTYPE} ]; then \ + echo "install -m 644 -D $(WAN_DIR)/wanpipe_lip.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanpipe_lip.${MODTYPE}"; \ install -m 644 -D $(WAN_DIR)/wanpipe_lip.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanpipe_lip.${MODTYPE}; \ fi @eval "./patches/rundepmod.sh" diff --git a/Makefile.old b/Makefile.old new file mode 100644 index 0000000..f4ba6e9 --- /dev/null +++ b/Makefile.old @@ -0,0 +1,225 @@ +# +# Makefile WANPIPE WAN Router Installation/Removal Makefile +# +# Copyright (c) 2007, Sangoma Technologies Inc. +# +# 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. +# ---------------------------------------------------------------------------- +# Author: Nenad Corbic +# + +PWD=$(shell pwd) +KBUILD_VERBOSE=0 + +#Default zaptel directory to be overwritten by user +ifndef ZAPDIR + ZAPDIR=/usr/src/zaptel +endif + +#Kernel version and location +ifndef KVER + KVER=$(shell uname -r) +endif +ifndef KMOD + KMOD=/lib/modules/$(KVER) +endif +ifndef KDIR + KDIR=$(KMOD)/build +endif +ifndef KINSTDIR + KINSTDIR=$(KMOD)/kernel +endif + +ifndef ARCH + ARCH=$(shell uname -m) +endif + +INSTALLPREFIX= + +#Local wanpipe includes +WINCLUDE=patches/kdrivers/include +HWECINC=patches/kdrivers/wanec/oct6100_api +KMODDIR=patches/kdrivers + +#Location of wanpipe source in release +WAN_DIR=$(PWD)/$(KMODDIR)/src/net +WANEC_DIR=$(PWD)/$(KMODDIR)/wanec +MODTYPE=ko + +#Setup include path and extra cflags +EXTRA_CFLAGS := -I$(PWD)/$(WINCLUDE) -I$(PWD)/$(WINCLUDE)/annexg -I$(PWD)/patches/kdrivers/wanec -D__LINUX__ +EXTRA_CFLAGS += -I$(WANEC_DIR) -I$(WANEC_DIR)/oct6100_api -I$(WANEC_DIR)/oct6100_api/include +EXTRA_CFLAGS += -I$(KDIR)/include/linux -I$(ZAPDIR) + +#Setup utility extra flags and include path +EXTRA_UTIL_FLAGS = -I$(PWD)/$(WINCLUDE) -I$(KDIR)/include/ -I$(INSTALLPREFIX)/include -I$(INSTALLPREFIX)/usr/include +EXTRA_UTIL_FLAGS += -I$(PWD)/patches/kdrivers/wanec -I$(PWD)/patches/kdrivers/wanec/oct6100_api/include + +ENABLE_WANPIPEMON_ZAP=NO + +#Check if zaptel exists +ifneq (,$(wildcard $(ZAPDIR)/zaptel.h)) + ZAPDIR_PRIV=$(ZAPDIR) + ENABLE_WANPIPEMON_ZAP=YES + EXTRA_CFLGS+= -DSTANDALONE_ZAPATA -DBUILDING_TONEZONE +else + ZAPDIR_PRIV= + ENABLE_WANPIPEMON_ZAP=NO +endif + +RM = @rm -rf +JUNK = *~ *.bak DEADJOE + + +# First pass, kernel Makefile reads module objects +ifneq ($(KERNELRELEASE),) +obj-m := sdladrv.o wanrouter.o wanpipe.o wanpipe_syncppp.o wanec.o + +# Second pass, the actual build. +else + +#This will check for zaptel, kenrel source and build utilites and kernel modules +#within local directory structure +all: _checkzap _checksrc all_util all_kmod + +#Build only kernel modules +all_kmod: _checkzap _checksrc _cleanoldwanpipe _check_kver + $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C $(KDIR) SUBDIRS=$(WAN_DIR) EXTRA_FLAGS="$(EXTRA_CFLAGS) $(shell cat ./patches/kfeatures)" ZAPDIR=$(ZAPDIR_PRIV) HOMEDIR=$(PWD) modules + + +#Clean utilites and kernel modules +clean: clean_util _cleanoldwanpipe + $(MAKE) -C $(KDIR) SUBDIRS=$(WAN_DIR) clean + @find patches/kdrivers -name '.*.cmd' | xargs rm -f + + +#Clean old wanpipe headers from linux include +_cleanoldwanpipe: _checksrc + @eval "./patches/build_links.sh" + @eval "./patches/clean_old_wanpipe.sh $(WINCLUDE) $(KDIR)/include/linux" + + +#Check for linux headers +_checksrc: + @if [ ! -e $(KDIR) ]; then \ + echo " Error linux headers/source not found: $(KDIR) !"; \ + echo ; \ + exit 1; \ + fi + @if [ ! -e $(KDIR)/.config ]; then \ + echo " Error linux headers/source not configured: missing $(KDIR)/.config !"; \ + echo ; \ + exit 1; \ + fi + @if [ ! -e $(KDIR)/include ]; then \ + echo " Error linux headers/source incomplete: missing $(KDIR)/include dir !"; \ + echo ; \ + exit 1; \ + fi + +_check_kver: + @eval "./patches/kern_i_private_check.sh $(KDIR)" + @echo > ./patches/kfeatures; + @if [ -e ./patches/i_private_found ]; then \ + echo "-DWANPIPE_USE_I_PRIVATE " >> ./patches/kfeatures; \ + fi + +#Check for zaptel +_checkzap: + @echo + @echo " +--------- Wanpipe Build Info --------------+" + @echo + @if [ ! -e $(ZAPDIR)/zaptel.h ]; then \ + echo " Compiling Wanpipe without ZAPTEL Support!"; \ + ZAPDIR_PRIV=; \ + ENABLE_WANPIPEMON_ZAP=NO; \ + else \ + echo " Compiling Wanpipe with ZAPTEL Support!"; \ + echo " Zaptel Dir: $(ZAPDIR)"; \ + echo; \ + eval "$(PWD)/patches/sangoma-zaptel-patch.sh $(ZAPDIR)"; \ + ZAPDIR_PRIV=$(ZAPDIR); \ + ENABLE_WANPIPEMON_ZAP=YES; \ + echo ; \ + echo "Please recompile and reinstall ZAPTEL after installation"; \ + fi + @echo + @echo " +-------------------------------------------+" + @echo + @sleep 2; + +#Install all utilities etc and modules +install: install_util install_etc install_kmod install_inc + +#Install kernel modules only +install_kmod: + install -m 644 -D $(WAN_DIR)/wanrouter.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanrouter.${MODTYPE} + install -m 644 -D $(WAN_DIR)/af_wanpipe.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/af_wanpipe.${MODTYPE} + install -m 644 -D $(WAN_DIR)/wanec.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanec.${MODTYPE} + install -m 644 -D $(WAN_DIR)/wan_aften.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wan_aften.${MODTYPE} + install -m 644 -D $(WAN_DIR)/sdladrv.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/sdladrv.${MODTYPE} + install -m 644 -D $(WAN_DIR)/wanpipe.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe.${MODTYPE} + @rm -f $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe_syncppp.${MODTYPE} + @if [ -f $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} ]; then \ + install -m 644 -D $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe_syncppp.${MODTYPE}; \ + fi + @rm -f $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanpipe_lip.${MODTYPE}; + @if [ -f $(WAN_DIR)/wanpipe_lip.${MODTYPE} ]; then \ + install -m 644 -D $(WAN_DIR)/wanpipe_lip.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanpipe_lip.${MODTYPE}; \ + fi + @eval "./patches/rundepmod.sh" + +endif + +#Compile utilities only +all_util: + $(MAKE) -C util all EXTRA_FLAGS="$(EXTRA_UTIL_FLAGS)" SYSINC="$(PWD)/$(WINCLUDE) -I $(PWD)/api/libsangoma/include" CC=$(CC) \ + PREFIX=$(INSTALLPREFIX) HOSTCFLAGS="$(EXTRA_UTIL_FLAGS)" ARCH=$(ARCH) + $(MAKE) -C util all_wancfg EXTRA_FLAGS="$(EXTRA_UTIL_FLAGS)" SYSINC="$(PWD)/$(WINCLUDE) -I$(PWD)/api/libsangoma/include" CC=$(CC) \ + PREFIX=$(INSTALLPREFIX) HOSTCFLAGS="$(EXTRA_UTIL_FLAGS)" HOSTCFLAGS="$(EXTRA_UTIL_FLAGS)" ARCH=$(ARCH) + +#Clean utilities only +clean_util: + $(MAKE) -C util clean SYSINC=$(PWD)/$(WINCLUDE) CC=$(CC) PREFIX=$(INSTALLPREFIX) + +#Install utilities only +install_util: + $(MAKE) -C util install SYSINC=$(PWD)/$(WINCLUDE) CC=$(CC) PREFIX=$(INSTALLPREFIX) + +#Install etc files +install_etc: + @if [ ! -e $(INSTALLPREFIX)/etc/wanpipe ]; then \ + mkdir -p $(INSTALLPREFIX)/etc/wanpipe; \ + fi + @if [ ! -e $(INSTALLPREFIX)/etc/wanpipe/wanrouter.rc ]; then \ + install -D -m 644 samples/wanrouter.rc $(INSTALLPREFIX)/etc/wanpipe/wanrouter.rc; \ + fi + @if [ ! -e $(INSTALLPREFIX)/etc/wanpipe/lib ]; then \ + mkdir -p $(INSTALLPREFIX)/etc/wanpipe/lib; \ + fi + @\cp -f util/wancfg_legacy/lib/* $(INSTALLPREFIX)/etc/wanpipe/lib/ + @\cp -rf firmware $(INSTALLPREFIX)/etc/wanpipe/ + @if [ ! -f $(INSTALLPREFIX)/etc/wanpipe/interfaces ]; then \ + mkdir -p $(INSTALLPREFIX)/etc/wanpipe/interfaces; \ + fi + @\cp -rf samples $(INSTALLPREFIX)/etc/wanpipe + @if [ ! -d $(INSTALLPREFIX)/etc/wanpipe/scripts ]; then \ + mkdir -p $(INSTALLPREFIX)/etc/wanpipe/scripts; \ + fi + @\cp -rf wan_ec $(INSTALLPREFIX)/etc/wanpipe/ + @install -D -m 755 samples/wanrouter $(INSTALLPREFIX)/usr/sbin/wanrouter + @echo + @echo "Wanpipe etc installed in $(INSTALLPREFIX)/etc/wanpipe"; + @echo + +install_inc: + @if [ -e $(INSTALLPREFIX)/usr/include/wanpipe ]; then \ + \rm -rf $(INSTALLPREFIX)/usr/include/wanpipe; \ + fi + @\mkdir -p $(INSTALLPREFIX)/usr/include/wanpipe + @\cp -f $(PWD)/patches/kdrivers/include/*.h $(INSTALLPREFIX)/usr/include/wanpipe/ + @\cp -rf $(PWD)/patches/kdrivers/wanec/oct6100_api/include/ $(INSTALLPREFIX)/usr/include/wanpipe/oct6100_api + @\cp -rf $(PWD)/patches/kdrivers/wanec/*.h $(INSTALLPREFIX)/usr/include/wanpipe/ diff --git a/Setup b/Setup index ab65f07..ba1d5ab 100755 --- a/Setup +++ b/Setup @@ -9,6 +9,7 @@ # as published by the Free Software Foundation; either version # 2 of the License, or (at your option) any later version. # ---------------------------------------------------------------------------- +# Oct 26, 2007 Konrad Hammel Updated minor start script bug # Nov 27, 2005 David Rokhvarg Added Echo Debugging option # Mar 18, 2002 Nenad Corbic Added BSCSTRM protocol # Mar 01, 2002 Nenad Corbic Added option to split rpm build into @@ -268,7 +269,7 @@ banner() clearscr echo -e "\t----------------------------------------------------------" echo -e "\t WANPIPE v$PROD_VER Installation Script" - echo -e "\t Copyright (c) 1995-2007, Sangoma Technologies Inc." + echo -e "\t Copyright (c) 1995-2008, Sangoma Technologies Inc." echo -e "\t----------------------------------------------------------" echo "" return 0 @@ -538,8 +539,6 @@ prepare() missing_packages=$missing_packages"libtermcap-devel " fi - echo -n "Checking for yacc..." - echo -n "Checking for yacc..." eval "type yacc 2> /dev/null > /dev/null" if [ $? -eq 0 ]; then @@ -1456,7 +1455,7 @@ create_mataconf() fi - if [ -f /etc/wanpipe/wanrouter.rc ]; then + if [ -f $ROOT/etc/wanpipe/wanrouter.rc ]; then . /etc/wanpipe/wanrouter.rc fi @@ -1570,7 +1569,60 @@ ENDOFTEXT # ---------------------------------------------------------------------------- # Install initialization scripts. # ---------------------------------------------------------------------------- + install_init() +{ + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + return 0 + fi + + if [ $NO_AUTO_START -eq 1 ]; then + return 0; + fi + banner + cat << ENDOFTEXT + +WANPIPE BOOTSTRAP CONFIGURATION + +Your system uses System V -style initialization scripts. You have an option +to add router start-up script to those scripts so that the router will start +automatically when system enters multi-user mode and shut down when it enters +single-user mode or when it is halted. + +i.e. By selecting this option WANPIPE will startup on system bootup and + stop on system shutdown. + +ENDOFTEXT + + getyn "Would you like to install WANPIPE start-up scripts?" || return 0 + + cd $PROD_HOME/util/wancfg_zaptel + eval "./wancfg_zaptel.pl --silent --install_boot_script" + + if [ $? -ne 0 ]; then + echo "Failed to install boot scripts" + fi + + if [ "$TDM_PROT" = "YES" ]; then + getyn "Would you like to auto-execute ztcfg after wanrouter start?" || return 0 + if [ ! -d $WAN_CONF_DIR/scripts ]; then + eval "\mkdir -p $WAN_CONF_DIR/scripts >/dev/null 2>/dev/null" + fi + eval "\cp -f $PROD_HOME/samples/wanpipe_zaptel_start $WAN_CONF_DIR/scripts/start > /dev/null 2> /dev/null" + if [ ! -f $WAN_CONF_DIR/scripts/start ]; then + echo "Error: Could not copy auto-ztcfg script" + fi + fi + + cd $PROD_HOME + +} + +# ---------------------------------------------------------------------------- +# Old Install initialization scripts. +# ---------------------------------------------------------------------------- + +install_init_old() { if [ "$PKG_NAME" = "wanpipe-lite" ]; then return 0 @@ -1642,8 +1694,8 @@ ENDOFTEXT getyn "Would you like to auto-execute ztcfg after wanrouter start?" || return 0 if [ ! -d $WAN_CONF_DIR/scripts ]; then eval "\mkdir -p $WAN_CONF_DIR/scripts >/dev/null 2>/dev/null" - fi - eval "\cp -f $PROD_HOME/samples/wanpipe_zaptel_start $WAN_CONF_DIR/scripts/start >/dev/null 2>/dev/null" + fi + eval "\cp -f $PROD_HOME/samples/wanpipe_zaptel_start $WAN_CONF_DIR/scripts/start > /dev/null 2> /dev/null" if [ ! -f $WAN_CONF_DIR/scripts/start ]; then echo "Error: Could not copy auto-ztcfg script" fi @@ -1922,8 +1974,15 @@ WARNING: The Linux source in $SOURCEDIR has not been configured. cd $PROD_HOME/api + if [ $superuser = "YES" ] && [ -z $ROOT ]; then + eval "find /usr/local/lib -name 'libsangoma*' > /dev/null 2>/dev/null" + if [ $? -eq 0 ]; then + eval "find /usr/local/lib -name 'libsangoma*' | xargs rm > /dev/null 2>/dev/null" + fi + fi + cd libsangoma - eval "./configure --prefix=$ROOT/usr/include >> $CMP_LOG 2>> $CMP_LOG" + eval "./configure --prefix=$ROOT/usr >> $CMP_LOG 2>> $CMP_LOG" eval "make clean >> $CMP_LOG 2>> $CMP_LOG" eval "make CC=$CC SYSINC=$SOURCEDIR/include >> $CMP_LOG 2>> $CMP_LOG" if [ $? -eq 0 ]; then @@ -1934,33 +1993,10 @@ WARNING: The Linux source in $SOURCEDIR has not been configured. fi eval "make install >> $CMP_LOG 2>> $CMP_LOG" + if [ $superuser = "YES" ] && [ -z $ROOT ]; then + eval "ldconfig > /dev/null 2> /dev/null" + fi - if [ $superuser = "YES" ]; then - if [ -d /etc/ld.so.conf.d ]; then - if [ ! -e $ROOT/etc/ld.so.conf.d/ ]; then - \mkdir -p $ROOT/etc/ld.so.conf.d/ - fi - \cp -f libsangoma.so.conf $ROOT/etc/ld.so.conf.d/ - - if [ $superuser = "YES" ]; then - eval "ldconfig" - fi - elif [ -f /etc/ld.so.conf ]; then - if [ $superuser = "YES" ]; then - cat /etc/ld.so.conf libsangoma.so.conf > ldconf.$$ - mv ldconf.$$ /etc/ld.so.conf - eval "ldconfig" - fi - else - echo - echo "Warning: LD Conf files not found in /etc directory" - echo "Please add /usr/local/lib to the LD_LIBRARY_PATH" - echo - eval "ldconfig" - pause - fi - fi - echo echo -n "Compiling WANPIPE API Development Utilities ..." @@ -2240,12 +2276,12 @@ function build_kernel_module() local_link=$local_link" $file.o " done - echo "make MODULE_NAME=$modname OBJS=\"$ofiles\" CC=$CC KDIR=$SOURCEDIR \ + echo "make MODULE_NAME=$modname OBJS=\"$ofiles\" SUBDIRS=$PWD CC=$CC KDIR=$SOURCEDIR \ EXTRA_CFLAGS=\"-D__LINUX__ $PROTOCOL_DEFINES $extra_flags \"" >> $CMP_BUILD chmod 755 $CMP_BUILD - make MODULE_NAME=$modname OBJS="$ofiles" CC=$CC KBUILD_VERBOSE=$KBUILD_VERBOSE KDIR=$SOURCEDIR \ + make MODULE_NAME=$modname OBJS="$ofiles" CC=$CC SUBDIRS=$PWD KBUILD_VERBOSE=$KBUILD_VERBOSE KDIR=$SOURCEDIR \ EXTRA_CFLAGS="-D__LINUX__ $PROTOCOL_DEFINES $extra_flags " >> $CMP_LOG 2>> $CMP_LOG if [ $? -ne 0 ]; then @@ -2345,7 +2381,7 @@ function build_wanec_module () local files="wanec_iface wanec_cmd wanec_utils wanec_dev $BTDIR/octapi_bt0 $LARGMATHDIR/octapi_largmath $LLMANDIR/octapi_llman $OCTAPIMIDIR/oct6100_mask_interrupts $OCTAPIDIR/oct6100_adpcm_chan $OCTAPIDIR/oct6100_channel $OCTAPIDIR/oct6100_chip_open $OCTAPIDIR/oct6100_chip_stats $OCTAPIDIR/oct6100_conf_bridge $OCTAPIDIR/oct6100_debug $OCTAPIDIR/oct6100_events $OCTAPIDIR/oct6100_interrupts $OCTAPIDIR/oct6100_memory $OCTAPIDIR/oct6100_miscellaneous $OCTAPIDIR/oct6100_mixer $OCTAPIDIR/oct6100_phasing_tsst $OCTAPIDIR/oct6100_playout_buf $OCTAPIDIR/oct6100_remote_debug $OCTAPIDIR/oct6100_tlv $OCTAPIDIR/oct6100_tone_detection $OCTAPIDIR/oct6100_tsi_cnct $OCTAPIDIR/oct6100_tsst $OCTAPIDIR/oct6100_user " - eval "make clean > /dev/null 2> /dev/null" + eval "make SUBDIRS=$PWD clean >> $CMP_BUILD 2>> $CMP_BUILD" if [ $KERN_VER -eq 24 ]; then if [ -e wanectmp ]; then @@ -2496,10 +2532,10 @@ function select_compilation_mode() 3. TDM Voice (Zaptel) + WAN Protocol Support -4. SMG (SS7) (Default for Asterisk SMG/SS7 install) +4. SMG (SS7) (Default for Asterisk/CallWeaver SMG/SS7 install) 5. SMG (SS7) + TDM Voice (Zaptel) - Default for: Asterisk SS7 + PRI + Default for: Asterisk/CallWeaver SS7 + PRI 6. TDM API Protocols: TDM API on AFT adapters: @@ -3197,6 +3233,13 @@ ENDOFTEXT #Find out our processor type. This is needed to properly #compile our modules. echo -n "Checking current processor type ..." + if [ -e $SOURCEDIR/include/linux/autoconf.h ]; then + grep "CONFIG_ARCH \"" $SOURCEDIR/include/linux/autoconf.h > /dev/null + if [ $? -eq 0 ] ; then + ARCH=`grep "CONFIG_ARCH \"" $SOURCEDIR/include/linux/autoconf.h | cut -d '"' -f2` + fi + fi + if [ -z $ARCH ]; then ARCH=`uname -m` fi @@ -4371,94 +4414,49 @@ function install_ssmg () echo "Installing Sangoma Media Gateway Daemon..." cd lib/libteletone/ - eval "./configure; make clean; make; make install " > /dev/null + eval "./configure --prefix=$ROOT/usr; make clean; make CC=$CC; make install " > /dev/null if [ $? -ne 0 ]; then echo "FAILED" return 1 fi - eval "ldconfig" - cd $PROD_HOME/$SSMG_DIR - -# Let smg install script install SMG components -#======================================================= - -# cd sangoma_mgd.trunk -# -# eval "make clean > /dev/null; make > /dev/null " -# if [ $? -ne 0 ]; then -# echo "FAILED" -# return 1 -# fi -# eval "make install > /dev/null " -# -# echo "Installing Sangoma Media Gateway Daemon...DONE" - -# eval "type asterisk > /dev/null 2> /dev/null" -# if [ $? -ne 0 ]; then -# echo "Error: Asterisk not installed!" -# echo "Please install Asterisk first then retry SSMG installation!" -# return 1 -# fi - -# echo -# echo "Installing Chan Woomera into Asterisk..." -# echo -# install_chan_woomera -# if [ $? -ne 0 ]; then -# echo "Error: Failed to install chan_woomera into Asterisk!" -# echo "Check that Asterisk is installed or Call Sangoma Tech Support" -# echo -# return 1 -# fi -#========================================================= + if [ $superuser = "YES" ]; then + eval "ldconfig" + fi cd $PROD_HOME/$SSMG_DIR cd sangoma_mgd.trunk - if [ ! -f /etc/asterisk/woomera.conf ]; then - cp woomera.conf /etc/asterisk - fi - - echo "Installing Chan Woomera into Asterisk...DONE" - echo - - if [ ! -f /usr/sbin/smgss7_ctrl ]; then - cp smgss7_ctrl /usr/sbin/ - fi getyn "Add Woomera config in Asterisk Extensions and Iax Conf" if [ $? -ne 0 ]; then return 0; fi - if [ -f /etc/asterisk/extensions.conf ]; then - eval "grep -i woomera /etc/asterisk/extensions.conf 2> /dev/null > /dev/null" + if [ -f $ROOT/etc/asterisk/extensions.conf ]; then + eval "grep -i woomera $ROOT/etc/asterisk/extensions.conf 2> /dev/null > /dev/null" if [ $? -ne 0 ]; then - cat /etc/asterisk/extensions.conf ./conf/woomera_ext.conf > conf.$$ - mv conf.$$ /etc/asterisk/extensions.conf + cat $ROOT/etc/asterisk/extensions.conf ./conf/woomera_ext.conf > conf.$$ + mv conf.$$ $ROOT/etc/asterisk/extensions.conf echo "Asterisk extensions.conf file updated with woomera config" else echo "Asterisk extensions.conf already updated" fi - else - echo "Warning: Asterisk extensions.conf file not found!" fi - if [ -f /etc/asterisk/iax.conf ]; then - eval "grep -i ss7 /etc/asterisk/iax.conf 2> /dev/null > /dev/null" + if [ -f $ROOT/etc/asterisk/iax.conf ]; then + eval "grep -i ss7 $ROOT/etc/asterisk/iax.conf 2> /dev/null > /dev/null" if [ $? -ne 0 ]; then - cat /etc/asterisk/iax.conf ./conf/woomera_iax.conf > conf.$$ - mv conf.$$ /etc/asterisk/iax.conf + cat $ROOT/etc/asterisk/iax.conf ./conf/woomera_iax.conf > conf.$$ + mv conf.$$ $ROOT/etc/asterisk/iax.conf echo "Asterisk iax.conf file updated with ss7 guest config" else echo "Asterisk iax.conf already updated" fi - else - echo "Warning: Asterisk extensions.conf file not found!" fi + pause return 0 @@ -4512,6 +4510,7 @@ function install_all () echo "Installing sample api code in $ROOT/etc/wanpipe/api" \cp -rf api $ROOT/etc/wanpipe \cp -rf samples $ROOT/etc/wanpipe + \cp -rf util/wanec_apilib /etc/wanpipe/api if [ ! -d $ROOT/etc/wanpipe/scripts ]; then @@ -5374,8 +5373,13 @@ function find_zap_dirs () echo echo "Looking for zaptel directory in /usr/src ..." echo "-------------------------------------------" + if [ "$zapdirs" = "" ]; then zapdirs=`find /usr/src -maxdepth 2 -name 'zaptel*' | xargs ` + if [ -d "/usr/src/zaptel" ]; then + zapdirs="/usr/src/zaptel "$zapdirs + fi + fi unset zapdir_array; @@ -5383,7 +5387,6 @@ function find_zap_dirs () if [ -f $PROD_HOME/zaptel/zaptel.path ]; then zapextradir=`cat $PROD_HOME/zaptel/zaptel.path` fi - cnt=1 for dir in $zapdirs do @@ -5391,7 +5394,11 @@ function find_zap_dirs () continue fi - if [ ! -f $dir/zaptel.h ]; then + if [ ! -f $dir/zaptel.h ];then + continue; + fi + + if [ "$dir" = "/usr/src/zaptel" ] && [ $cnt -ne 1 ]; then continue; fi @@ -5401,6 +5408,7 @@ function find_zap_dirs () cnt=$((cnt+1)) done + if [ $cnt -eq 1 ]; then echo echo "No zaptel dirs found in /usr/src " @@ -5432,7 +5440,8 @@ function find_zap_dirs () # echo "d2: Download Latest 1.2" # echo "d4: Download Latest 1.4" echo "(ctrl-c to Exit)" - echo -n "Please select working zaptel directory [1-9][m]: " + echo -n "Please select working zaptel directory [1-$((cnt-1))][m]: " + response=1 @@ -5859,13 +5868,28 @@ ENDOFTEXT fi - eval "grep ZT_DCHAN_TX_V2 $ZAPTEL_INSTALL_DIR/* 2> /dev/null > /dev/null" - if [ $? -eq 0 ]; then - TDM_DCHAN="(DCHAN)" - PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN" - echo "Sangoma DCHAN Patch detected in zaptel" - fi + #Check for new zaptel hw hdlc option + if [ -f $ZAPTEL_INSTALL_DIR/zaptel-base.c ]; then + eval "grep hdlc_hard_xmit $ZAPTEL_INSTALL_DIR/zaptel-base.c > /dev/null 2> /dev/null" + if [ $? -eq 0 ] ; then + echo "Native Zaptel HW HDLC Support Detected - No patch required" + echo "Zaptel source unmodified" + + TDM_DCHAN="(DCHAN)" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL " + fi + fi + #Check if dchan patch is already enabled + if [ "$TDM_DCHAN" = "" ]; then + eval "grep ZT_DCHAN_TX_V2 $ZAPTEL_INSTALL_DIR/* 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + TDM_DCHAN="(DCHAN)" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN" + echo "Sangoma DCHAN Patch detected in zaptel" + zaptel_modified=1 + fi + fi if [ "$TDM_DCHAN" = "" ]; then echo @@ -5881,9 +5905,11 @@ ENDOFTEXT TDM_DCHAN="(DCHAN)" echo " Zaptel DCHAN Patch successful" echo + zaptel_modified=1 elif [ $result -eq 1 ]; then TDM_DCHAN="(DCHAN)" echo + zaptel_modified=1 else echo "Zaptel Update Failed!" echo @@ -5959,7 +5985,6 @@ ENDOFTEXT fi TDM_PROT=YES - zaptel_modified=1; if [ $zaptel_modified ] && [ $zaptel_modified -eq 1 ] && [ "$ZAPTEL_COMPILE_DISABLE" = "NO" ]; then echo getyn "Recompile/reinstall Zaptel (recommended) ?" @@ -6296,11 +6321,11 @@ KERNEL_UNAME=`uname -r` PKG_NAME=wanpipe DISTR_NAME="WANPIPE" PROD=wanrouter -PROD_VER=3.2.1 +PROD_VER=3.2.2 PROD_HOME=`pwd` -META_CONF=$PROD_HOME/$PROD.rc +WAN_CONF_DIR=/etc/wanpipe +META_CONF=$WAN_CONF_DIR/$PROD.rc WAN_INTR_DIR=$PROD_HOME/interfaces -WAN_CONF_DIR=$PROD_HOME PROD_CONF=$WAN_CONF_DIR/wanpipe1.conf PROD_PATCH=$PROD_HOME/patches PROD_INIT=/usr/sbin/ @@ -6919,15 +6944,17 @@ you know what you are doing :) exit 1 fi - - $PROD_HOME/Setup install --silent --builddir=$PROD_HOME/$build_dir --with-linux=$SOURCEDIR --arch=$ARCH --protocol=$PROTS --ss7_user_id=$SS7_USER_ID --noautostart --no-zaptel-compile --zaptel-path=$ZAPTEL_INSTALL_DIR + if [ $TDM_PROT = "YES" ]; then + $PROD_HOME/Setup install --silent --builddir=$PROD_HOME/$build_dir --with-linux=$SOURCEDIR --arch=$ARCH --protocol=$PROTS --ss7_user_id=$SS7_USER_ID --noautostart --no-zaptel-compile --zaptel-path=$ZAPTEL_INSTALL_DIR --usr-cc=$CC + else + $PROD_HOME/Setup install --silent --builddir=$PROD_HOME/$build_dir --with-linux=$SOURCEDIR --arch=$ARCH --protocol=$PROTS --ss7_user_id=$SS7_USER_ID --noautostart --usr-cc=$CC + fi if [ $? -ne 0 ]; then echo "Error: WANPIPE Installation Failed!" exit 1; fi - if [ "$setup_cmd" = "buildrpm" ]; then compile_aft_firmware_util detect_rpm_build_utility @@ -7101,7 +7128,7 @@ prepare || exit 1 apply_patches || exit 1 compile_drivers || exit 1 install_init || exit 1 -install_config || exit 1 +install_config || exit 1 compile_src || exit 1 install_all install_ssmg diff --git a/api/Makefile b/api/Makefile index 84cf1c5..0e751ce 100644 --- a/api/Makefile +++ b/api/Makefile @@ -26,6 +26,6 @@ clean: make -C fr clean make -C bitstrm clean make -C bisync clean - make -C tdm_api clean + make -C tdmapi clean make -C lib/hdlc clean # make -C ss7 clean diff --git a/api/aft/Makefile b/api/aft/Makefile index dfb5fad..a91b46a 100644 --- a/api/aft/Makefile +++ b/api/aft/Makefile @@ -16,7 +16,7 @@ SYSINC=/usr/src/linux/include endif VPATH = $(SYSINC) -DIR_EC_APILIB=/common/wantools/wanec_apilib +DIR_EC_APILIB=../wanec_apilib SRC_EC_APILIB=$(DIR_EC_APILIB)/wanec_api.c $(DIR_EC_APILIB)/wanec_api_lib.c INC_EC_APILIB=-I/usr/include/wanpipe/oct6100_api -I$(DIR_EC_APILIB) @@ -26,6 +26,8 @@ CFLAGS += -I/usr/include/wanpipe TARGETS=aft_api TARGETS+= aft_api_events +TARGETS+= aft_integrity +TARGETS+= aft_echo #TARGETS+= aft_api_ss7 #TARGETS+= aft_api_check #TARGETS+= aft_tdm_api @@ -50,5 +52,11 @@ aft_tdm_api: aft_tdm_api.c ../lib/lib_api.c aft_api_ss7: aft_api_ss7.c ../lib/lib_api.c $(CC) $(CFLAGS) -o $@ $^ +aft_integrity: aft_integrity.c ../lib/lib_api.c + $(CC) $(CFLAGS) -o $@ $^ + +aft_echo: aft_echo.c ../lib/lib_api.c + $(CC) $(CFLAGS) -o $@ $^ + clean: rm -f $(TARGETS) diff --git a/api/aft/aft_api b/api/aft/aft_api new file mode 100755 index 0000000..4e54e6a Binary files /dev/null and b/api/aft/aft_api differ diff --git a/api/aft/aft_api.c b/api/aft/aft_api.c index 84b1e24..53bc59a 100644 --- a/api/aft/aft_api.c +++ b/api/aft/aft_api.c @@ -90,8 +90,8 @@ int MakeConnection(void) printf("\nConnecting to card %s, interface %s prot %x\n", card_name, if_name,htons(PVC_PROT)); - strcpy( sa.sll_device, if_name); - strcpy( sa.sll_card, card_name); + strcpy( (char*)sa.sll_device, if_name); + strcpy( (char*)sa.sll_card, card_name); sa.sll_protocol = htons(PVC_PROT); sa.sll_family=AF_WANPIPE; @@ -543,7 +543,7 @@ int main(int argc, char* argv[]) proceed=init_args(argc,argv); if (proceed != WAN_TRUE){ - usage(argv[0]); + usage((unsigned char*)argv[0]); return -1; } diff --git a/api/aft/aft_api_events b/api/aft/aft_api_events new file mode 100755 index 0000000..0356331 Binary files /dev/null and b/api/aft/aft_api_events differ diff --git a/api/aft/aft_api_events.c b/api/aft/aft_api_events.c index d830c88..3dc039e 100644 --- a/api/aft/aft_api_events.c +++ b/api/aft/aft_api_events.c @@ -85,8 +85,8 @@ int MakeConnection(void) printf("\nConnecting to card %s, interface %s prot %x\n", card_name, if_name,htons(PVC_PROT)); - strcpy( sa.sll_device, if_name); - strcpy( sa.sll_card, card_name); + strcpy( (char*)sa.sll_device, if_name); + strcpy( (char*)sa.sll_card, card_name); sa.sll_protocol = htons(PVC_PROT); sa.sll_family=AF_WANPIPE; @@ -234,6 +234,7 @@ tone_try_again: return 0; } +#if 0 static int ringdetect_event_ctrl(u_int8_t mode, int channel, int tone) { api_tx_hdr_t api_tx_hdr; @@ -258,6 +259,7 @@ ringdetect_try_again: return 0; } +#endif static int event_decode(api_rx_hdr_t *rx_hdr) { @@ -727,7 +729,7 @@ int main(int argc, char* argv[]) proceed=init_args(argc,argv); if (proceed != WAN_TRUE){ - usage(argv[0]); + usage((unsigned char*)argv[0]); return -1; } diff --git a/api/aft/aft_echo b/api/aft/aft_echo new file mode 100755 index 0000000..5ba2b46 Binary files /dev/null and b/api/aft/aft_echo differ diff --git a/api/aft/aft_echo.c b/api/aft/aft_echo.c new file mode 100644 index 0000000..73cc25e --- /dev/null +++ b/api/aft/aft_echo.c @@ -0,0 +1,316 @@ +/***************************************************************************** +* chdlc_api.c CHDLC API: Receive Module +* +* Author(s): Gideon Hack & Nenad Corbic +* +* Copyright: (c) 1995-2001 Sangoma Technologies Inc. +* +* 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. +* ============================================================================ +* Description: +* +* The chdlc_api.c utility will bind to a socket to a chdlc network +* interface, and continously tx and rx packets to an from the sockets. +* +* This example has been written for a single interface in mind, +* where the same process handles tx and rx data. +* +* A real world example, should use different processes to handle +* tx and rx spearately. +*/ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lib_api.h" + +#define FALSE 0 +#define TRUE 1 + +#define LGTH_CRC_BYTES 0 +#define MAX_TX_DATA 5000 /* Size of tx data */ +#define MAX_RX_DATA MAX_TX_DATA + + +#define SOCK_TIMEOUT 1 + + +/*=================================================== + * Golobal data + *==================================================*/ + +unsigned char HDLC_streaming = FALSE; +unsigned short Rx_lgth; + +unsigned char Rx_data[MAX_RX_DATA]; +unsigned char Tx_data[MAX_TX_DATA]; +int sock; + + +/*=================================================== + * Function Prototypes + *==================================================*/ +int MakeConnection(void); +void handle_socket( void); + + + + +/*=================================================== + * MakeConnection + * + * o Create a Socket + * o Bind a socket to a wanpipe network interface + * (Interface name is supplied by the user) + *==================================================*/ + +int MakeConnection(void) +{ + struct wan_sockaddr_ll sa; + + memset(&sa,0,sizeof(struct wan_sockaddr_ll)); + errno = 0; + sock = socket(AF_WANPIPE, SOCK_RAW, 0); + if( sock < 0 ) { + perror("Socket"); + return(FALSE); + } /* if */ + + printf("\nConnecting to router %s, interface %s\n", card_name, if_name); + + strcpy( (char*)sa.sll_device, if_name); + strcpy( (char*)sa.sll_card, card_name); + sa.sll_protocol = htons(PVC_PROT); + sa.sll_family=AF_WANPIPE; + + if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){ + perror("bind"); + printf("Failed to bind a socket to %s interface\n",if_name); + exit(0); + } + printf("Socket bound to %s\n\n",if_name); + + return(TRUE); + +} + + +/*=========================================================== + * handle_socket + * + * o Tx/Rx data to and from the socket + * o Cast received data to an api_rx_element_t data type + * o The received packet contains 16 bytes header + * + * ------------------------------------------ + * | 16 bytes | X bytes ... + * ------------------------------------------ + * Header Data + * + * RX DATA: + * -------- + * Each rx data packet contains the 16 byte header! + * + * o Rx 16 byte data structure: + * + * typedef struct { + * unsigned char error_flag PACKED; + * unsigned short time_stamp PACKED; + * unsigned char reserved[13] PACKED; + * } api_rx_hdr_t; + * + * typedef struct { + * api_rx_hdr_t api_rx_hdr PACKED; + * void * data PACKED; + * } api_rx_element_t; + * + * error_flag: + * bit 0: incoming frame was aborted + * bit 1: incoming frame has a CRC error + * bit 2: incoming frame has an overrun eror + * + * time_stamp: + * absolute time value in ms. + * + * TX_DATA: + * -------- + * Each tx data packet MUST contain a 16 byte header! + * + * o Tx 16 byte data structure + * + * typedef struct { + * unsigned char attr PACKED; + * unsigned char reserved[15] PACKED; + * } api_tx_hdr_t; + * + * typedef struct { + * api_tx_hdr_t api_tx_hdr PACKED; + * void * data PACKED; + * } api_tx_element_t; + * + * Currently the chdlc device driver doesn't use any of + * the above fields. Thus, the user can set the 16 bytes + * to ZERO. + * + */ + +void handle_socket(void) +{ + unsigned int Rx_count,Tx_count,Tx_length; + api_tx_element_t * api_tx_el; + fd_set ready,write,oob; + int err; + struct timeval tv; + tv.tv_usec = 0; + tv.tv_sec = SOCK_TIMEOUT; + + + Rx_count = 0; + Tx_count = 0; + Tx_length = tx_size; + + printf("\n\nSocket Handler: Rx=%d Tx=%i TxCnt=%i TxLen=%i TxDelay=%i RxCnt=%i\n", + read_enable,write_enable,tx_cnt,tx_size,tx_delay,rx_cnt); + + /* If running HDLC_STREAMING then the received CRC bytes + * will be passed to the application as part of the + * received data. + */ + + api_tx_el = (api_tx_element_t*)&Tx_data[0]; + memset(&Tx_data[0],0,MAX_TX_DATA); + + while (1) { + err = ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0); + printf("Interface %s state is %s (%d)\n", + if_name, + (err == 0) ? "CONNECTED" : + (err == 1) ? "DISCONNECTED" : + "CONNECTING",err); + + if (err < 0) { + printf("Error interface down %s sock disconnected! (%s)\n", + if_name,strerror(errno)); + return; + } + + if (err > 0) { + printf("Waiting for interface %s to come up!\n",if_name); + sleep(10); + } else { + break; + } + } + + for(;;) { + FD_ZERO(&ready); + FD_ZERO(&write); + FD_ZERO(&oob); + FD_SET(sock,&oob); + FD_SET(sock,&ready); + + tv.tv_usec = 0; + tv.tv_sec = SOCK_TIMEOUT; + + if (write_enable){ + FD_SET(sock,&write); + } + + fflush(stdout); + err= select(sock + 1,&ready, NULL, &oob, NULL); + + if (err < 0) { + printf("Error: inteface down: %s socket disconnected %s\n", + if_name,strerror(errno)); + break; + + } else if (err == 0) { + /* Timeout do something */ + + } else { + + if (FD_ISSET(sock,&oob)){ + + err = recv(sock, Rx_data, MAX_RX_DATA, MSG_OOB); + + if(err < 0 ) { + printf("Failed to receive OOB %i , %i\n", Rx_count, err); + err = ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0); + printf("Sock state is %s\n", + (err == 0) ? "CONNECTED" : + (err == 1) ? "DISCONNECTED" : + "CONNECTING"); + break; + } + + printf("Got OOB exception: Link Down !\n"); + break; + } + + + if (FD_ISSET(sock,&ready)){ + + err = recv(sock, Rx_data, MAX_RX_DATA, 0); + + /* err indicates bytes received */ + if (err > 0){ + Rx_count++; + err = send(sock, Rx_data, err, 0); + Tx_count++; + printf("Rx Len=%i Rx=%i Tx=%i : Echo Ok\r", + err-sizeof(api_rx_hdr_t), Tx_count,Rx_count); + } else { + printf("\nError receiving data\n"); + break; + } + + } + } + } + + close (sock); +} + +/*************************************************************** + * Main: + * + * o Make a socket connection to the driver. + * o Call handle_socket() to read/write the socket + * + **************************************************************/ + + +int main(int argc, char* argv[]) +{ + int proceed; + + proceed=init_args(argc,argv); + if (proceed != WAN_TRUE){ + usage((unsigned char*)argv[0]); + return -1; + } + + proceed = MakeConnection(); + if(proceed == WAN_TRUE){ + handle_socket(); + return 0; + } + + return 1; +}; diff --git a/api/aft/aft_integrity b/api/aft/aft_integrity new file mode 100755 index 0000000..de6c382 Binary files /dev/null and b/api/aft/aft_integrity differ diff --git a/api/aft/aft_integrity.c b/api/aft/aft_integrity.c new file mode 100644 index 0000000..7844900 --- /dev/null +++ b/api/aft/aft_integrity.c @@ -0,0 +1,421 @@ +/***************************************************************************** +* chdlc_api.c CHDLC API: Receive Module +* +* Author(s): Gideon Hack & Nenad Corbic +* +* Copyright: (c) 1995-2001 Sangoma Technologies Inc. +* +* 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. +* ============================================================================ +* Description: +* +* The chdlc_api.c utility will bind to a socket to a chdlc network +* interface, and continously tx and rx packets to an from the sockets. +* +* This example has been written for a single interface in mind, +* where the same process handles tx and rx data. +* +* A real world example, should use different processes to handle +* tx and rx spearately. +*/ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lib_api.h" + +#define FALSE 0 +#define TRUE 1 + +#define LGTH_CRC_BYTES 0 +#define MAX_TX_DATA 5000 /* Size of tx data */ +#define MAX_RX_DATA MAX_TX_DATA + + +#define SOCK_TIMEOUT 1 + + +/*=================================================== + * Golobal data + *==================================================*/ + +unsigned char HDLC_streaming = FALSE; +unsigned short Rx_lgth; + +unsigned char Rx_data[MAX_RX_DATA]; +unsigned char Tx_data[MAX_TX_DATA]; +int sock; + + +/*=================================================== + * Function Prototypes + *==================================================*/ +int MakeConnection(void); +void handle_socket( void); + +static unsigned char test_data[]={0x00,0x5A, 0xAA, 0xA5, 0xFF}; +static unsigned char tx_index=0; + + + +/*=================================================== + * MakeConnection + * + * o Create a Socket + * o Bind a socket to a wanpipe network interface + * (Interface name is supplied by the user) + *==================================================*/ + +int MakeConnection(void) +{ + struct wan_sockaddr_ll sa; + + memset(&sa,0,sizeof(struct wan_sockaddr_ll)); + errno = 0; + sock = socket(AF_WANPIPE, SOCK_RAW, 0); + if( sock < 0 ) { + perror("Socket"); + return(FALSE); + } /* if */ + + printf("\nConnecting to router %s, interface %s\n", card_name, if_name); + + strcpy( (char*)sa.sll_device, if_name); + strcpy( (char*)sa.sll_card, card_name); + sa.sll_protocol = htons(PVC_PROT); + sa.sll_family=AF_WANPIPE; + + if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){ + perror("bind"); + printf("Failed to bind a socket to %s interface\n",if_name); + exit(0); + } + printf("Socket bound to %s\n\n",if_name); + + return(TRUE); + +} + + +void init_tx_pattern(void) +{ + api_tx_element_t * api_tx_el; + unsigned char *data; + int i; + + memset(&Tx_data[0],0,MAX_TX_DATA); + + /* Initialize the tx packet. The 16 byte header must + * be inserted before tx data. In CHDLC protocol, + * the tx x25 header is not used, thus it can be + * set to zero */ + api_tx_el = (api_tx_element_t*)&Tx_data[0]; + data = (unsigned char *)api_tx_el->data; + + for (i=0;i= sizeof(test_data)){ + tx_index=0; + } + } +} + + +/*=========================================================== + * handle_socket + * + * o Tx/Rx data to and from the socket + * o Cast received data to an api_rx_element_t data type + * o The received packet contains 16 bytes header + * + * ------------------------------------------ + * | 16 bytes | X bytes ... + * ------------------------------------------ + * Header Data + * + * RX DATA: + * -------- + * Each rx data packet contains the 16 byte header! + * + * o Rx 16 byte data structure: + * + * typedef struct { + * unsigned char error_flag PACKED; + * unsigned short time_stamp PACKED; + * unsigned char reserved[13] PACKED; + * } api_rx_hdr_t; + * + * typedef struct { + * api_rx_hdr_t api_rx_hdr PACKED; + * void * data PACKED; + * } api_rx_element_t; + * + * error_flag: + * bit 0: incoming frame was aborted + * bit 1: incoming frame has a CRC error + * bit 2: incoming frame has an overrun eror + * + * time_stamp: + * absolute time value in ms. + * + * TX_DATA: + * -------- + * Each tx data packet MUST contain a 16 byte header! + * + * o Tx 16 byte data structure + * + * typedef struct { + * unsigned char attr PACKED; + * unsigned char reserved[15] PACKED; + * } api_tx_hdr_t; + * + * typedef struct { + * api_tx_hdr_t api_tx_hdr PACKED; + * void * data PACKED; + * } api_tx_element_t; + * + * Currently the chdlc device driver doesn't use any of + * the above fields. Thus, the user can set the 16 bytes + * to ZERO. + * + */ + +void handle_socket(void) +{ + unsigned int Rx_count,Tx_count,Tx_length; + api_rx_element_t* api_rx_el; + api_tx_element_t * api_tx_el; + fd_set ready,write,oob; + int err,i; + int no_CRC_bytes_Rx = LGTH_CRC_BYTES; + struct timeval tv; + tv.tv_usec = 0; + tv.tv_sec = SOCK_TIMEOUT; + + + Rx_count = 0; + Tx_count = 0; + Tx_length = tx_size; + + printf("\n\nSocket Handler: Rx=%d Tx=%i TxCnt=%i TxLen=%i TxDelay=%i RxCnt=%i\n", + read_enable,write_enable,tx_cnt,tx_size,tx_delay,rx_cnt); + + /* If running HDLC_STREAMING then the received CRC bytes + * will be passed to the application as part of the + * received data. + */ + + api_tx_el = (api_tx_element_t*)&Tx_data[0]; + memset(&Tx_data[0],0,MAX_TX_DATA); + + init_tx_pattern(); + + while (1) { + err = ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0); + printf("Interface %s state is %s (%d)\n", + if_name, + (err == 0) ? "CONNECTED" : + (err == 1) ? "DISCONNECTED" : + "CONNECTING",err); + + if (err < 0) { + printf("Error interface down %s sock disconnected! (%s)\n", + if_name,strerror(errno)); + return; + } + + if (err > 0) { + printf("Waiting for interface %s to come up!\n",if_name); + sleep(10); + } else { + break; + } + } + + for(;;) { + FD_ZERO(&ready); + FD_ZERO(&write); + FD_ZERO(&oob); + FD_SET(sock,&oob); + FD_SET(sock,&ready); + + tv.tv_usec = 0; + tv.tv_sec = SOCK_TIMEOUT; + + if (write_enable){ + FD_SET(sock,&write); + } + + fflush(stdout); + err= select(sock + 1,&ready, &write, &oob, &tv); + + if (err < 0) { + printf("Error: inteface down: %s socket disconnected %s\n", + if_name,strerror(errno)); + break; + + } else if (err == 0) { + /* Timeout do someting if you like */ + + } else { + + if (FD_ISSET(sock,&oob)){ + + err = recv(sock, Rx_data, MAX_RX_DATA, MSG_OOB); + + if(err < 0 ) { + printf("Failed to receive OOB %i , %i\n", Rx_count, err); + err = ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0); + printf("Sock state is %s\n", + (err == 0) ? "CONNECTED" : + (err == 1) ? "DISCONNECTED" : + "CONNECTING"); + break; + } + + printf("Got OOB exception: Link Down !\n"); + break; + } + + + if (FD_ISSET(sock,&ready)){ + + err = recv(sock, Rx_data, MAX_RX_DATA, 0); + + /* err indicates bytes received */ + if (err > 0){ + + api_rx_el = (api_rx_element_t*)&Rx_data[0]; + + /* Check the packet length */ + Rx_lgth = err - sizeof(api_rx_hdr_t)-no_CRC_bytes_Rx; + if(Rx_lgth<=0) { + printf("\nShort frame received (%d)\n", + Rx_lgth); + Rx_count++; + continue; + } + + ++Rx_count; + + if (Rx_lgth != Tx_length){ + printf("Rx Error cnt %i: Rx length %i not equal to %i\n", + Rx_count,Rx_lgth,Tx_length); + break; + } + + for (i=0;idata)[i] != + ((unsigned char*)api_tx_el->data)[i]){ + printf("Rx Error cnt=%i: Packet corruption on offset %i\n", + Rx_count,i); + break; + } + } + + if (verbose) { + printf("Tx Len=%i Tx=%i Rx=%i : Data Ok\r", + Tx_length, Tx_count,Rx_count); + } + + if (Rx_count == tx_cnt){ + init_tx_pattern(); + Rx_count=0; + write_enable=1; + } + + } else { + printf("\nError receiving data\n"); + break; + } + + } + + if (FD_ISSET(sock,&write)){ + + err = send(sock,Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0); + + if (err <= 0){ + if (errno == EBUSY){ + /* Socket busy try sending again !*/ + }else{ + /* Check socket state */ + err = ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0); + printf("Sock state is %s\n", + (err == 0) ? "CONNECTED" : + (err == 1) ? "DISCONNECTED" : + "CONNECTING"); + + printf("Failed to send %i \n",errno); + perror("Send: "); + break; + } + }else{ + ++Tx_count; + if (verbose && Rx_count < 1) { + printf("Tx Len=%i Tx=%i Rx=%i : Data Ok\r", + Tx_length, Tx_count,Rx_count); + } + + } + } + + if (tx_delay){ + sleep(tx_delay); + } + + if (tx_size && Tx_count == tx_cnt){ + write_enable=0; + Tx_count=0; + } + } + } + + close (sock); +} + +/*************************************************************** + * Main: + * + * o Make a socket connection to the driver. + * o Call handle_socket() to read/write the socket + * + **************************************************************/ + + +int main(int argc, char* argv[]) +{ + int proceed; + + proceed=init_args(argc,argv); + if (proceed != WAN_TRUE){ + usage((unsigned char*)argv[0]); + return -1; + } + + proceed = MakeConnection(); + if(proceed == WAN_TRUE){ + handle_socket(); + return 0; + } + + return 1; +}; diff --git a/api/chdlc/chdlc_echo b/api/chdlc/chdlc_echo index ae8a764..3523279 100755 Binary files a/api/chdlc/chdlc_echo and b/api/chdlc/chdlc_echo differ diff --git a/api/lib/hdlc/wanpipe_hdlc.o b/api/lib/hdlc/wanpipe_hdlc.o deleted file mode 100644 index cd08352..0000000 Binary files a/api/lib/hdlc/wanpipe_hdlc.o and /dev/null differ diff --git a/api/lib/lib_api.c b/api/lib/lib_api.c index 0f1dce0..a2f873f 100644 --- a/api/lib/lib_api.c +++ b/api/lib/lib_api.c @@ -50,18 +50,18 @@ int tx_data=-1; int tx_ss7_type=0; int rx_ss7_timer=0; -unsigned char card_name[WAN_IFNAME_SZ]; -unsigned char if_name[WAN_IFNAME_SZ]; +char card_name[WAN_IFNAME_SZ]; +char if_name[WAN_IFNAME_SZ]; -unsigned char sw_if_name[WAN_IFNAME_SZ]; -unsigned char sw_card_name[WAN_IFNAME_SZ]; +char sw_if_name[WAN_IFNAME_SZ]; +char sw_card_name[WAN_IFNAME_SZ]; -unsigned char tx_file[WAN_IFNAME_SZ]; -unsigned char rx_file[WAN_IFNAME_SZ]; +char tx_file[WAN_IFNAME_SZ]; +char rx_file[WAN_IFNAME_SZ]; -unsigned char daddr[TX_ADDR_STR_SZ]; -unsigned char saddr[TX_ADDR_STR_SZ]; -unsigned char udata[TX_ADDR_STR_SZ]; +char daddr[TX_ADDR_STR_SZ]; +char saddr[TX_ADDR_STR_SZ]; +char udata[TX_ADDR_STR_SZ]; int files_used=0; int verbose=0; diff --git a/api/lib/lib_api.h b/api/lib/lib_api.h index 824696b..fc33b2e 100644 --- a/api/lib/lib_api.h +++ b/api/lib/lib_api.h @@ -38,14 +38,14 @@ extern int cause; extern int card_cnt; extern int i_cnt; -extern unsigned char tx_file[WAN_IFNAME_SZ]; -extern unsigned char rx_file[WAN_IFNAME_SZ]; +extern char tx_file[WAN_IFNAME_SZ]; +extern char rx_file[WAN_IFNAME_SZ]; #define TX_ADDR_STR_SZ 100 -extern unsigned char daddr[TX_ADDR_STR_SZ]; -extern unsigned char saddr[TX_ADDR_STR_SZ]; -extern unsigned char udata[TX_ADDR_STR_SZ]; +extern char daddr[TX_ADDR_STR_SZ]; +extern char saddr[TX_ADDR_STR_SZ]; +extern char udata[TX_ADDR_STR_SZ]; #define TX_FILE_USED 1 @@ -58,8 +58,8 @@ extern int init_args(int argc, char *argv[]); extern void usage(unsigned char *api_name); extern void u_delay(int usec); -extern unsigned char card_name[WAN_IFNAME_SZ]; -extern unsigned char if_name[WAN_IFNAME_SZ]; +extern char card_name[WAN_IFNAME_SZ]; +extern char if_name[WAN_IFNAME_SZ]; -extern unsigned char sw_if_name[WAN_IFNAME_SZ]; -extern unsigned char sw_card_name[WAN_IFNAME_SZ]; +extern char sw_if_name[WAN_IFNAME_SZ]; +extern char sw_card_name[WAN_IFNAME_SZ]; diff --git a/api/libsangoma/.deps/libsangoma_la-libsangoma.Plo b/api/libsangoma/.deps/libsangoma_la-libsangoma.Plo index 5191063..1a925df 100644 --- a/api/libsangoma/.deps/libsangoma_la-libsangoma.Plo +++ b/api/libsangoma/.deps/libsangoma_la-libsangoma.Plo @@ -25,21 +25,21 @@ libsangoma_la-libsangoma.lo libsangoma_la-libsangoma.o: libsangoma.c \ /usr/lib/gcc/i386-redhat-linux/4.1.1/include/syslimits.h \ /usr/include/limits.h /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/limits.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/limits.h \ /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \ /usr/include/bits/sockaddr.h \ - /lib/modules/2.6.18-8.el5/build/include/asm/socket.h \ - /lib/modules/2.6.18-8.el5/build/include/asm/sockios.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm/socket.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm/sockios.h \ /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \ - /lib/modules/2.6.18-8.el5/build/include/asm/ioctls.h \ - /lib/modules/2.6.18-8.el5/build/include/asm/ioctl.h \ - /lib/modules/2.6.18-8.el5/build/include/asm-generic/ioctl.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm/ioctls.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm/ioctl.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm-generic/ioctl.h \ /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h \ /usr/include/sys/signal.h /usr/include/signal.h \ /usr/include/bits/signum.h /usr/include/bits/siginfo.h \ /usr/include/bits/sigaction.h /usr/include/bits/sigcontext.h \ - /lib/modules/2.6.18-8.el5/build/include/asm/sigcontext.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/compiler.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm/sigcontext.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/compiler.h \ /usr/include/bits/sigstack.h /usr/include/sys/ucontext.h \ /usr/include/bits/sigthread.h /usr/include/sys/wait.h \ /usr/include/sys/resource.h /usr/include/bits/resource.h \ @@ -47,25 +47,25 @@ libsangoma_la-libsangoma.lo libsangoma_la-libsangoma.o: libsangoma.c \ /usr/include/bits/byteswap.h /usr/include/string.h \ /usr/include/bits/string.h /usr/include/bits/string2.h \ /usr/include/errno.h /usr/include/bits/errno.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/errno.h \ - /lib/modules/2.6.18-8.el5/build/include/asm/errno.h \ - /lib/modules/2.6.18-8.el5/build/include/asm-generic/errno.h \ - /lib/modules/2.6.18-8.el5/build/include/asm-generic/errno-base.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/errno.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm/errno.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm-generic/errno.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm-generic/errno-base.h \ /usr/include/fcntl.h /usr/include/bits/fcntl.h /usr/include/sys/stat.h \ /usr/include/bits/stat.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/if.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/types.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/posix_types.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/stddef.h \ - /lib/modules/2.6.18-8.el5/build/include/asm/posix_types.h \ - /lib/modules/2.6.18-8.el5/build/include/asm/types.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/socket.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/hdlc/ioctl.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/if.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/types.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/posix_types.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/stddef.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm/posix_types.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/asm/types.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/socket.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/hdlc/ioctl.h \ /usr/include/poll.h /usr/include/sys/poll.h /usr/include/bits/poll.h \ ../../patches/kdrivers/include/linux/wanpipe_defines.h \ ../../patches/kdrivers/include/linux/wanpipe_version.h \ ../../patches/kdrivers/include/linux/wanpipe_kernel.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/version.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/version.h \ ../../patches/kdrivers/include/linux/wanpipe_cfg.h \ ../../patches/kdrivers/include/linux/sdla_56k.h \ ../../patches/kdrivers/include/linux/sdla_te1.h \ @@ -81,7 +81,7 @@ libsangoma_la-libsangoma.lo libsangoma_la-libsangoma.o: libsangoma.c \ ../../patches/kdrivers/include/linux/wanpipe_tdm_api.h \ ../../patches/kdrivers/include/linux/wanpipe_includes.h \ ../../patches/kdrivers/include/linux/if_wanpipe.h \ - /lib/modules/2.6.18-8.el5/build/include/linux/sockios.h \ + /lib/modules/2.6.18-8.1.15.el5/build/include/linux/sockios.h \ ../../patches/kdrivers/include/linux/wanpipe_codec_iface.h libsangoma.h: @@ -184,7 +184,7 @@ libsangoma.h: /usr/include/bits/local_lim.h: -/lib/modules/2.6.18-8.el5/build/include/linux/limits.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/limits.h: /usr/include/bits/posix2_lim.h: @@ -192,19 +192,19 @@ libsangoma.h: /usr/include/bits/sockaddr.h: -/lib/modules/2.6.18-8.el5/build/include/asm/socket.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm/socket.h: -/lib/modules/2.6.18-8.el5/build/include/asm/sockios.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm/sockios.h: /usr/include/sys/ioctl.h: /usr/include/bits/ioctls.h: -/lib/modules/2.6.18-8.el5/build/include/asm/ioctls.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm/ioctls.h: -/lib/modules/2.6.18-8.el5/build/include/asm/ioctl.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm/ioctl.h: -/lib/modules/2.6.18-8.el5/build/include/asm-generic/ioctl.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm-generic/ioctl.h: /usr/include/bits/ioctl-types.h: @@ -222,9 +222,9 @@ libsangoma.h: /usr/include/bits/sigcontext.h: -/lib/modules/2.6.18-8.el5/build/include/asm/sigcontext.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm/sigcontext.h: -/lib/modules/2.6.18-8.el5/build/include/linux/compiler.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/compiler.h: /usr/include/bits/sigstack.h: @@ -256,13 +256,13 @@ libsangoma.h: /usr/include/bits/errno.h: -/lib/modules/2.6.18-8.el5/build/include/linux/errno.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/errno.h: -/lib/modules/2.6.18-8.el5/build/include/asm/errno.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm/errno.h: -/lib/modules/2.6.18-8.el5/build/include/asm-generic/errno.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm-generic/errno.h: -/lib/modules/2.6.18-8.el5/build/include/asm-generic/errno-base.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm-generic/errno-base.h: /usr/include/fcntl.h: @@ -272,21 +272,21 @@ libsangoma.h: /usr/include/bits/stat.h: -/lib/modules/2.6.18-8.el5/build/include/linux/if.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/if.h: -/lib/modules/2.6.18-8.el5/build/include/linux/types.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/types.h: -/lib/modules/2.6.18-8.el5/build/include/linux/posix_types.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/posix_types.h: -/lib/modules/2.6.18-8.el5/build/include/linux/stddef.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/stddef.h: -/lib/modules/2.6.18-8.el5/build/include/asm/posix_types.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm/posix_types.h: -/lib/modules/2.6.18-8.el5/build/include/asm/types.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/asm/types.h: -/lib/modules/2.6.18-8.el5/build/include/linux/socket.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/socket.h: -/lib/modules/2.6.18-8.el5/build/include/linux/hdlc/ioctl.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/hdlc/ioctl.h: /usr/include/poll.h: @@ -300,7 +300,7 @@ libsangoma.h: ../../patches/kdrivers/include/linux/wanpipe_kernel.h: -/lib/modules/2.6.18-8.el5/build/include/linux/version.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/version.h: ../../patches/kdrivers/include/linux/wanpipe_cfg.h: @@ -332,6 +332,6 @@ libsangoma.h: ../../patches/kdrivers/include/linux/if_wanpipe.h: -/lib/modules/2.6.18-8.el5/build/include/linux/sockios.h: +/lib/modules/2.6.18-8.1.15.el5/build/include/linux/sockios.h: ../../patches/kdrivers/include/linux/wanpipe_codec_iface.h: diff --git a/api/libsangoma/Makefile b/api/libsangoma/Makefile index e4c018a..fce2039 100644 --- a/api/libsangoma/Makefile +++ b/api/libsangoma/Makefile @@ -205,7 +205,7 @@ localstatedir = ${prefix}/var mandir = ${prefix}/man mkdir_p = mkdir -p -- oldincludedir = /usr/include -prefix = /usr/include +prefix = /usr program_transform_name = s,x,x, sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com diff --git a/api/libsangoma/config.log b/api/libsangoma/config.log index 7d87523..5a17b0e 100644 --- a/api/libsangoma/config.log +++ b/api/libsangoma/config.log @@ -4,7 +4,7 @@ running configure, to aid debugging if configure makes a mistake. It was created by libsangoma configure 1.0.0, which was generated by GNU Autoconf 2.59. Invocation command line was - $ ./configure --prefix=/usr/include + $ ./configure --prefix=/usr ## --------- ## ## Platform. ## @@ -12,9 +12,9 @@ generated by GNU Autoconf 2.59. Invocation command line was hostname = tesla uname -m = i686 -uname -r = 2.6.18-8.el5 +uname -r = 2.6.18-8.1.15.el5 uname -s = Linux -uname -v = #1 SMP Thu Mar 15 19:57:35 EDT 2007 +uname -v = #1 SMP Mon Oct 22 08:32:04 EDT 2007 /usr/bin/uname -p = unknown /bin/uname -X = unknown @@ -38,6 +38,7 @@ PATH: /usr/sbin PATH: /usr/bin PATH: /usr/sbin/scripts PATH: /root/bin +PATH: /usr/sbin/scripts PATH: /bin PATH: /sbin PATH: /usr/bin @@ -1031,7 +1032,7 @@ localstatedir='${prefix}/var' mandir='${prefix}/man' mkdir_p='mkdir -p --' oldincludedir='/usr/include' -prefix='/usr/include' +prefix='/usr' program_transform_name='s,x,x,' sbindir='${exec_prefix}/sbin' sharedstatedir='${prefix}/com' diff --git a/api/libsangoma/config.status b/api/libsangoma/config.status index e7936a6..c68e011 100755 --- a/api/libsangoma/config.status +++ b/api/libsangoma/config.status @@ -298,7 +298,7 @@ Report bugs to ." ac_cs_version="\ libsangoma config.status 1.0.0 configured by ./configure, generated by GNU Autoconf 2.59, - with options \"'--prefix=/usr/include'\" + with options \"'--prefix=/usr'\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation @@ -377,8 +377,8 @@ if $ac_cs_silent; then fi if $ac_cs_recheck; then - echo "running /bin/sh ./configure " '--prefix=/usr/include' $ac_configure_extra_args " --no-create --no-recursion" >&6 - exec /bin/sh ./configure '--prefix=/usr/include' $ac_configure_extra_args --no-create --no-recursion + echo "running /bin/sh ./configure " '--prefix=/usr' $ac_configure_extra_args " --no-create --no-recursion" >&6 + exec /bin/sh ./configure '--prefix=/usr' $ac_configure_extra_args --no-create --no-recursion fi # @@ -452,7 +452,7 @@ s,@PACKAGE_VERSION@,1.0.0,;t t s,@PACKAGE_STRING@,libsangoma 1.0.0,;t t s,@PACKAGE_BUGREPORT@,anthmct@yahoo.com,;t t s,@exec_prefix@,${prefix},;t t -s,@prefix@,/usr/include,;t t +s,@prefix@,/usr,;t t s,@program_transform_name@,s,x,x,,;t t s,@bindir@,${exec_prefix}/bin,;t t s,@sbindir@,${exec_prefix}/sbin,;t t diff --git a/api/libsangoma/libsangoma.c b/api/libsangoma/libsangoma.c index cc9ec54..6fc9025 100644 --- a/api/libsangoma/libsangoma.c +++ b/api/libsangoma/libsangoma.c @@ -24,14 +24,23 @@ #ifndef WP_TDM_EVENT_FE_ALARM -#warning "Warning: TDM FE ALARM not supported by driver" +#warning "Note: TDM FE ALARM not supported by driver" #endif #ifndef WP_TDMAPI_EVENT_DTMF -#warning "Warning: TDM EVENTS not supported by driver" +#warning "Note: TDM DTMF EVENTS not supported by driver" #endif +#ifndef WP_TDMAPI_EVENT_RING +#warning "Note: TDM RING EVENTS not supported by driver" +#endif + +#ifndef WP_TDMAPI_EVENT_RXHOOK +#warning "Note: TDM RXHOOK EVENTS not supported by driver" +#endif + + #if defined(WIN32) @@ -912,6 +921,11 @@ int sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return 0; } +#endif + + +#ifdef WP_TDMAPI_EVENT_RXHOOK + int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { int err; @@ -944,6 +958,10 @@ int sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return 0; } +#endif + +#ifdef WP_TDMAPI_EVENT_RING + int sangoma_tdm_enable_ring_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { int err; diff --git a/api/tdmapi/Makefile b/api/tdmapi/Makefile index b7d16e5..3797681 100644 --- a/api/tdmapi/Makefile +++ b/api/tdmapi/Makefile @@ -22,9 +22,9 @@ CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib/hdlc -I../l TARGETS = aft_tdm_voice_api TARGETS += aft_tdm_hdlc_test TARGETS += aft_tdm_voice_api_rbs -TARGETS += aft_tdm_voice_api_dtmf -TARGETS += aft_tdm_voice_api_rm_dtmf -TARGETS += aft_tdm_voice_api_rxhook +#TARGETS += aft_tdm_voice_api_dtmf +#TARGETS += aft_tdm_voice_api_rm_dtmf +#TARGETS += aft_tdm_voice_api_rxhook ####### RULES ################################################################ diff --git a/api/tdmapi/aft_tdm_hdlc_test b/api/tdmapi/aft_tdm_hdlc_test deleted file mode 100755 index 9b8d37b..0000000 Binary files a/api/tdmapi/aft_tdm_hdlc_test and /dev/null differ diff --git a/api/tdmapi/aft_tdm_voice_api b/api/tdmapi/aft_tdm_voice_api deleted file mode 100755 index bc238c9..0000000 Binary files a/api/tdmapi/aft_tdm_voice_api and /dev/null differ diff --git a/api/tdmapi/aft_tdm_voice_api.c b/api/tdmapi/aft_tdm_voice_api.c index c3bc330..4f1682e 100644 --- a/api/tdmapi/aft_tdm_voice_api.c +++ b/api/tdmapi/aft_tdm_voice_api.c @@ -414,7 +414,7 @@ int main(int argc, char* argv[]) proceed=init_args(argc,argv); if (proceed != WAN_TRUE){ - usage(argv[0]); + usage((unsigned char*)argv[0]); return -1; } diff --git a/api/tdmapi/aft_tdm_voice_api_dtmf b/api/tdmapi/aft_tdm_voice_api_dtmf deleted file mode 100755 index 3ff0382..0000000 Binary files a/api/tdmapi/aft_tdm_voice_api_dtmf and /dev/null differ diff --git a/api/tdmapi/aft_tdm_voice_api_dtmf.c b/api/tdmapi/aft_tdm_voice_api_dtmf.c deleted file mode 100644 index 492db3f..0000000 --- a/api/tdmapi/aft_tdm_voice_api_dtmf.c +++ /dev/null @@ -1,254 +0,0 @@ -/***************************************************************************** -* aft_api.c AFT T1/E1: HDLC API Sample Code -* -* Author(s): Nenad Corbic -* -* Copyright: (c) 2003-2004 Sangoma Technologies Inc. -* -* 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. -* ============================================================================ -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lib_api.h" - -#define MAX_TX_DATA 5000 /* Size of tx data */ -#define MAX_FRAMES 5000 /* Number of frames to transmit */ - -#define MAX_RX_DATA 5000 - -unsigned short Rx_lgth; - -unsigned char Rx_data[MAX_RX_DATA]; -unsigned char Tx_data[MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)]; - -/* Prototypes */ -int MakeConnection(void); -void handle_span_chan( void); -void sig_end(int sigid); - -int dev_fd; -FILE *tx_fd=NULL,*rx_fd=NULL; -wanpipe_tdm_api_t tdm_api; - - -/*************************************************** -* HANDLE SOCKET -* -* o Read a socket -* o Cast data received to api_rx_element_t data type -* o The received packet contains 16 bytes header -* -* ------------------------------------------ -* | 16 bytes | X bytes ... -* ------------------------------------------ -* Header Data -* -* o Data structures: -* ------------------ -* typedef struct { -* union { -* struct { -* unsigned char _event_type; -* unsigned char _rbs_rx_bits; -* unsigned int _time_stamp; -* }wp_event; -* struct { -* unsigned char _rbs_rx_bits; -* unsigned int _time_stamp; -* }wp_rx; -* unsigned char reserved[16]; -* }wp_rx_hdr_u; -* #define wp_api_event_type wp_rx_hdr_u.wp_event._event_type -* #define wp_api_event_rbs_rx_bits wp_rx_hdr_u.wp_event._rbs_rx_bits -* #define wp_api_event_time_stamp wp_rx_hdr_u.wp_event._time_stamp -* } wp_tdm_api_rx_hdr_t; -* -* typedef struct { -* wp_tdm_api_rx_hdr_t hdr; -* unsigned char data[1]; -* } wp_tdm_api_rx_element_t; -* -* typedef struct { -* union { -* struct { -* unsigned char _rbs_rx_bits; -* unsigned int _time_stamp; -* }wp_tx; -* unsigned char reserved[16]; -* }wp_tx_hdr_u; -* #define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp -* } wp_tdm_api_tx_hdr_t; -* -* typedef struct { -* wp_tdm_api_tx_hdr_t hdr; -* unsigned char data[1]; -* } wp_tdm_api_tx_element_t; -* -* #define WPTDM_A_BIT 0x08 -* #define WPTDM_B_BIT 0x04 -* #define WPTDM_C_BIT 0x02 -* #define WPTDM_D_BIT 0x01 -* -*/ - -void handle_span_chan(void) -{ - unsigned int Rx_count,Tx_count,Tx_length; - int err; - -#if 0 - int rlen; - int stream_sync=0; -#endif - - Rx_count = 0; - Tx_count = 0; - - if (tdm_api.wp_tdm_cmd.hdlc) { - Tx_length = tx_size; - } else { - Tx_length = tdm_api.wp_tdm_cmd.usr_mtu_mru; - } - - printf("\n\nSocket Handler: Rx=%d Tx=%i TxCnt=%i TxLen=%i TxDelay=%i\n", - read_enable,write_enable,tx_cnt,tx_size,tx_delay); - - sangoma_tdm_enable_dtmf_events(dev_fd, &tdm_api); - - /* Main Rx Tx OOB routine */ - for(;;) { - - err = sangoma_socket_waitfor(dev_fd, 1000, POLLPRI); - printf("ret:%d\n", err); - if (err){ - err=sangoma_tdm_read_event(dev_fd,&tdm_api); - if(err < 0 ) { - printf("Failed to receive EVENT %d\n", err); - break; - } - - printf("GOT OOB EXCEPTION CMD Exiting\n"); - } - - if (++Rx_count >= rx_cnt){ - break; - } - - } - - sangoma_tdm_disable_dtmf_events(dev_fd, &tdm_api); - if (tx_fd){ - fclose(tx_fd); - } - if (rx_fd){ - fclose(rx_fd); - } - close (dev_fd); - - return; -} - -int dtmf_event (int fd, unsigned char digit, unsigned char type, unsigned char port) -{ - printf("%d: DTMV Event: %c (%s:%s)!\n", - fd, - digit, - (port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT", - (type == WAN_EC_TONE_PRESENT)?"PRESET":"STOP"); - return 0; -} - - -/*************************************************************** - * Main: - * - * o Make a socket connection to the driver. - * o Call handle_span_chan() to read the socket - * - **************************************************************/ - - -int main(int argc, char* argv[]) -{ - int proceed; - - proceed=init_args(argc,argv); - if (proceed != WAN_TRUE){ - usage(argv[0]); - return -1; - } - - signal(SIGINT,&sig_end); - memset(&tdm_api,0,sizeof(tdm_api)); - tdm_api.wp_tdm_event.wp_dtmf_event = &dtmf_event; - - printf("TDM DTMF PTR = %p\n",tdm_api.wp_tdm_event.wp_dtmf_event); - - dev_fd =-1; - - dev_fd = sangoma_open_tdmapi_span_chan(atoi(card_name),atoi(if_name)); - if( dev_fd < 0){ - printf("Failed to open span chan(%s:%d,%s:%d)\n", - card_name,atoi(card_name),if_name,atoi(if_name)); - exit (1); - } - printf("HANDLING SPAN %i CHAN %i FD=%i\n", - atoi(card_name),atoi(if_name),dev_fd); - - sangoma_tdm_set_codec(dev_fd,&tdm_api,WP_NONE); - sangoma_get_full_cfg(dev_fd, &tdm_api); - - handle_span_chan(); - close(dev_fd); - return 0; - - return 0; -}; - - -void sig_end(int sigid) -{ - - printf("Got Signal %i\n",sigid); - - sangoma_tdm_disable_dtmf_events(dev_fd, &tdm_api); - - if (tx_fd){ - fclose(tx_fd); - } - if (rx_fd){ - fclose(rx_fd); - } - - if (dev_fd){ - close (dev_fd); - } - - exit(1); -} - - - diff --git a/api/tdmapi/aft_tdm_voice_api_rbs b/api/tdmapi/aft_tdm_voice_api_rbs deleted file mode 100755 index d81f68c..0000000 Binary files a/api/tdmapi/aft_tdm_voice_api_rbs and /dev/null differ diff --git a/api/tdmapi/aft_tdm_voice_api_rbs.c b/api/tdmapi/aft_tdm_voice_api_rbs.c index 7e1a696..efaa45f 100644 --- a/api/tdmapi/aft_tdm_voice_api_rbs.c +++ b/api/tdmapi/aft_tdm_voice_api_rbs.c @@ -449,7 +449,7 @@ int main(int argc, char* argv[]) proceed=init_args(argc,argv); if (proceed != WAN_TRUE){ - usage(argv[0]); + usage((unsigned char*)argv[0]); return -1; } diff --git a/api/tdmapi/aft_tdm_voice_api_rm_dtmf b/api/tdmapi/aft_tdm_voice_api_rm_dtmf deleted file mode 100755 index 8163761..0000000 Binary files a/api/tdmapi/aft_tdm_voice_api_rm_dtmf and /dev/null differ diff --git a/api/tdmapi/aft_tdm_voice_api_rm_dtmf.c b/api/tdmapi/aft_tdm_voice_api_rm_dtmf.c deleted file mode 100644 index 872947a..0000000 --- a/api/tdmapi/aft_tdm_voice_api_rm_dtmf.c +++ /dev/null @@ -1,445 +0,0 @@ -/***************************************************************************** -* aft_api.c AFT T1/E1: HDLC API Sample Code -* -* Author(s): Nenad Corbic -* -* Copyright: (c) 2003-2004 Sangoma Technologies Inc. -* -* 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. -* ============================================================================ -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lib_api.h" - -#define MAX_TX_DATA 5000 /* Size of tx data */ -#define MAX_FRAMES 5000 /* Number of frames to transmit */ - -#define MAX_RX_DATA 5000 - -unsigned short Rx_lgth; - -unsigned char Rx_data[MAX_RX_DATA]; -unsigned char Tx_data[MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)]; - -/* Prototypes */ -int MakeConnection(void); -void handle_span_chan( void); -void sig_end(int sigid); - -int dev_fd; -FILE *tx_fd=NULL,*rx_fd=NULL; -wanpipe_tdm_api_t tdm_api; - - -/*************************************************** -* HANDLE SOCKET -* -* o Read a socket -* o Cast data received to api_rx_element_t data type -* o The received packet contains 16 bytes header -* -* ------------------------------------------ -* | 16 bytes | X bytes ... -* ------------------------------------------ -* Header Data -* -* o Data structures: -* ------------------ -* typedef struct { -* union { -* struct { -* unsigned char _event_type; -* unsigned char _rbs_rx_bits; -* unsigned int _time_stamp; -* }wp_event; -* struct { -* unsigned char _rbs_rx_bits; -* unsigned int _time_stamp; -* }wp_rx; -* unsigned char reserved[16]; -* }wp_rx_hdr_u; -* #define wp_api_event_type wp_rx_hdr_u.wp_event._event_type -* #define wp_api_event_rbs_rx_bits wp_rx_hdr_u.wp_event._rbs_rx_bits -* #define wp_api_event_time_stamp wp_rx_hdr_u.wp_event._time_stamp -* } wp_tdm_api_rx_hdr_t; -* -* typedef struct { -* wp_tdm_api_rx_hdr_t hdr; -* unsigned char data[1]; -* } wp_tdm_api_rx_element_t; -* -* typedef struct { -* union { -* struct { -* unsigned char _rbs_rx_bits; -* unsigned int _time_stamp; -* }wp_tx; -* unsigned char reserved[16]; -* }wp_tx_hdr_u; -* #define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp -* } wp_tdm_api_tx_hdr_t; -* -* typedef struct { -* wp_tdm_api_tx_hdr_t hdr; -* unsigned char data[1]; -* } wp_tdm_api_tx_element_t; -* -* #define WPTDM_A_BIT 0x08 -* #define WPTDM_B_BIT 0x04 -* #define WPTDM_C_BIT 0x02 -* #define WPTDM_D_BIT 0x01 -* -*/ - -void handle_span_chan(void) -{ - unsigned int Rx_count,Tx_count,Tx_length; - wp_tdm_api_rx_element_t* api_rx_el; - wp_tdm_api_tx_element_t * api_tx_el; - fd_set ready,write,oob; - int err,i; - -#if 0 - int rlen; - int stream_sync=0; -#endif - - Rx_count = 0; - Tx_count = 0; - - if (tdm_api.wp_tdm_cmd.hdlc) { - Tx_length = tx_size; - } else { - Tx_length = tdm_api.wp_tdm_cmd.usr_mtu_mru; - } - - printf("\n\nSocket Handler: Rx=%d Tx=%i TxCnt=%i TxLen=%i TxDelay=%i\n", - read_enable,write_enable,tx_cnt,tx_size,tx_delay); - - /* Initialize the Tx Data buffer */ - memset(&Tx_data[0],0,MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)); - - /* Cast the Tx data packet with the tx element - * structure. We must insert a 16 byte - * driver header, which driver will remove - * before passing packet out the physical port */ - api_tx_el = (wp_tdm_api_tx_element_t*)&Tx_data[0]; - - - /* Create a Tx packet based on user info, or - * by deafult incrementing number starting from 0 */ - for (i=0;idata[i] = (unsigned char)i; - }else{ -#if 0 - api_tx_el->data[i] = (unsigned char)tx_data+(i%4); -#else - api_tx_el->data[i] = (unsigned char)tx_data; -#endif - } - } - - sangoma_tdm_enable_rm_dtmf_events(dev_fd, &tdm_api); - - /* Main Rx Tx OOB routine */ - for(;;) { - - /* Initialize all select() descriptors */ - FD_ZERO(&ready); - FD_ZERO(&write); - FD_ZERO(&oob); - FD_SET(dev_fd,&oob); - FD_SET(dev_fd,&ready); - - if (write_enable){ - FD_SET(dev_fd,&write); - } - - /* Select will block, until: - * 1: OOB event, link level change - * 2: Rx data available - * 3: Interface able to Tx */ - - if(select(dev_fd + 1,&ready, &write, &oob, NULL)){ - - fflush(stdout); - if (FD_ISSET(dev_fd,&oob)){ - - /* An OOB event is pending, usually indicating - * a link level change */ - - err=sangoma_tdm_read_event(dev_fd,&tdm_api); - - if(err < 0 ) { - printf("Failed to receive OOB %i , %i\n", Rx_count, err); - err = ioctl(dev_fd,SIOC_WANPIPE_SOCK_STATE,0); - printf("Sock state is %s\n", - (err == 0) ? "CONNECTED" : - (err == 1) ? "DISCONNECTED" : - "CONNECTING"); - break; - } - - printf("GOT OOB EXCEPTION CMD Exiting\n"); - } - - - if (FD_ISSET(dev_fd,&ready)){ - - /* An Rx packet is pending - * 1: Read the rx packet into the Rx_data - * buffer. Confirm len > 0 - * - * 2: Cast Rx_data to the api_rx_element. - * Thus, removing a 16 byte header - * attached by the driver. - * - * 3. Check error_flag: - * CRC,Abort..etc - */ - - memset(Rx_data, 0, sizeof(Rx_data)); - - err = sangoma_readmsg_tdm(dev_fd, - Rx_data, - sizeof(wp_tdm_api_rx_hdr_t), - &Rx_data[sizeof(wp_tdm_api_rx_hdr_t)], - MAX_RX_DATA, 0); - - - if (!read_enable){ - goto bitstrm_skip_read; - } - - /* err indicates bytes received */ - if(err <= 0) { - printf("\nError receiving data\n"); - break; - } - - api_rx_el = (wp_tdm_api_rx_element_t*)&Rx_data[0]; - - /* Check the packet length */ - Rx_lgth = err; - if(Rx_lgth<=0) { - printf("\nShort frame received (%d)\n", - Rx_lgth); - return; - } - -#if 0 - if (api_rx_el->data[0] == tx_data && api_rx_el->data[1] == (tx_data+1)){ - if (!stream_sync){ - printf("GOT SYNC %x\n",api_rx_el->data[0]); - } - stream_sync=1; - }else{ - if (stream_sync){ - printf("OUT OF SYNC: %x\n",api_rx_el->data[0]); - } - } -#endif - - ++Rx_count; - - if (verbose){ - printf("Received %i Length = %i\n", - Rx_count,Rx_lgth); -#if 1 - printf("Data: "); - for(i=0;idata[i]); - } - printf("\n"); -#endif - }else{ - //putchar('R'); - } - - -#if 0 - switch(api_rx_el->hdr.wp_api_event_type){ - case WP_TDM_EVENT_DTMF: - printf("DTMV Event: %c (%s:%s)!\n", - api_rx_el->hdr.wp_api_event_dtmf_digit, - (api_rx_el->hdr.wp_api_event_dtmf_type&WP_TDM_EVENT_DTMF_ROUT)?"ROUT":"SOUT", - (api_rx_el->hdr.wp_api_event_dtmf_type&WP_TDM_EVENT_DTMF_PRESET)?"PRESET":"STOP"); - break; - case WP_TDM_EVENT_RXHOOK: - printf("RXHOOK Event: %s!\n", - (api_rx_el->hdr.wp_api_event_rxhook_state&WP_TDM_EVENT_RXHOOK_OFF)?"OFF-HOOK":"ON-HOOK"); - break; - case WP_TDM_EVENT_RING: - printf("RING Event: %s!\n", - (api_rx_el->hdr.wp_api_event_ring_state&WP_TDM_EVENT_RING_PRESENT)?"PRESENT":"STOP"); - break; - } -#endif - if (rx_cnt > 0 && Rx_count >= rx_cnt){ - break; - } -bitstrm_skip_read: -; - } - - if (FD_ISSET(dev_fd,&write)){ - - - err = sangoma_writemsg_tdm(dev_fd, - Tx_data,16, - &Tx_data[16], Tx_length, - 0); - if (err <= 0){ - if (errno == EBUSY){ - if (verbose){ - printf("Sock busy try again!\n"); - } - /* Socket busy try sending again !*/ - }else{ - printf("Faild to send %i \n",errno); - perror("Send: "); - break; - } - }else{ - - ++Tx_count; - - if (verbose){ - printf("Packet sent: Sent %i : %i\n", - err,Tx_count); - }else{ - //putchar('T'); - } - } - } - - if (tx_delay){ - usleep(tx_delay); - } - - if (tx_cnt && tx_size && Tx_count >= tx_cnt && !(files_used & TX_FILE_USED)){ - - write_enable=0; - if (rx_cnt > 0){ - /* Dont break let rx finish */ - }else{ - break; - } - } - } - } - - sangoma_tdm_disable_rm_dtmf_events(dev_fd, &tdm_api); - if (tx_fd){ - fclose(tx_fd); - } - if (rx_fd){ - fclose(rx_fd); - } - close (dev_fd); - - return; -} - -int dtmf_event (int fd, unsigned char digit, unsigned char type, unsigned char port) -{ - printf("%d: DTMV Event: %c (%s:%s)!\n", - fd, - digit, - (port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT", - (type == WAN_EC_TONE_PRESENT)?"PRESET":"STOP"); - return 0; -} - -/*************************************************************** - * Main: - * - * o Make a socket connection to the driver. - * o Call handle_span_chan() to read the socket - * - **************************************************************/ - - -int main(int argc, char* argv[]) -{ - int proceed; - - proceed=init_args(argc,argv); - if (proceed != WAN_TRUE){ - usage(argv[0]); - return -1; - } - - signal(SIGINT,&sig_end); - memset(&tdm_api,0,sizeof(tdm_api)); - tdm_api.wp_tdm_event.wp_dtmf_event = &dtmf_event; - - printf("TDM DTMF PTR = %p\n",tdm_api.wp_tdm_event.wp_dtmf_event); - - dev_fd =-1; - - dev_fd = sangoma_open_tdmapi_span_chan(1,1/*atoi(card_name),atoi(if_name)*/); - if( dev_fd < 0){ - printf("Failed to open span chan:%s:%s\n",card_name,if_name); - exit (1); - } - printf("HANDLING SPAN %i CHAN %i FD=%i\n", - atoi(card_name),atoi(if_name),dev_fd); - - sangoma_tdm_set_codec(dev_fd,&tdm_api,WP_NONE); - sangoma_get_full_cfg(dev_fd, &tdm_api); - - handle_span_chan(); - close(dev_fd); - return 0; - - return 0; -}; - - -void sig_end(int sigid) -{ - - printf("Got Signal %i\n",sigid); - - sangoma_tdm_disable_rm_dtmf_events(dev_fd, &tdm_api); - - if (tx_fd){ - fclose(tx_fd); - } - if (rx_fd){ - fclose(rx_fd); - } - - if (dev_fd){ - close (dev_fd); - } - - exit(1); -} - - - diff --git a/api/tdmapi/aft_tdm_voice_api_rxhook b/api/tdmapi/aft_tdm_voice_api_rxhook deleted file mode 100755 index 817dddc..0000000 Binary files a/api/tdmapi/aft_tdm_voice_api_rxhook and /dev/null differ diff --git a/api/tdmapi/aft_tdm_voice_api_rxhook.c b/api/tdmapi/aft_tdm_voice_api_rxhook.c deleted file mode 100644 index 949ee42..0000000 --- a/api/tdmapi/aft_tdm_voice_api_rxhook.c +++ /dev/null @@ -1,448 +0,0 @@ -/***************************************************************************** -* aft_api.c AFT T1/E1: HDLC API Sample Code -* -* Author(s): Nenad Corbic -* -* Copyright: (c) 2003-2004 Sangoma Technologies Inc. -* -* 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. -* ============================================================================ -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lib_api.h" - -#define MAX_TX_DATA 5000 /* Size of tx data */ -#define MAX_FRAMES 5000 /* Number of frames to transmit */ - -#define MAX_RX_DATA 5000 - -unsigned short Rx_lgth; - -unsigned char Rx_data[MAX_RX_DATA]; -unsigned char Tx_data[MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)]; - -/* Prototypes */ -int MakeConnection(void); -void handle_span_chan( void); -void sig_end(int sigid); - -int dev_fd; -FILE *tx_fd=NULL,*rx_fd=NULL; -wanpipe_tdm_api_t tdm_api; - - -/*************************************************** -* HANDLE SOCKET -* -* o Read a socket -* o Cast data received to api_rx_element_t data type -* o The received packet contains 16 bytes header -* -* ------------------------------------------ -* | 16 bytes | X bytes ... -* ------------------------------------------ -* Header Data -* -* o Data structures: -* ------------------ -* typedef struct { -* union { -* struct { -* unsigned char _event_type; -* unsigned char _rbs_rx_bits; -* unsigned int _time_stamp; -* }wp_event; -* struct { -* unsigned char _rbs_rx_bits; -* unsigned int _time_stamp; -* }wp_rx; -* unsigned char reserved[16]; -* }wp_rx_hdr_u; -* #define wp_api_event_type wp_rx_hdr_u.wp_event._event_type -* #define wp_api_event_rbs_rx_bits wp_rx_hdr_u.wp_event._rbs_rx_bits -* #define wp_api_event_time_stamp wp_rx_hdr_u.wp_event._time_stamp -* } wp_tdm_api_rx_hdr_t; -* -* typedef struct { -* wp_tdm_api_rx_hdr_t hdr; -* unsigned char data[1]; -* } wp_tdm_api_rx_element_t; -* -* typedef struct { -* union { -* struct { -* unsigned char _rbs_rx_bits; -* unsigned int _time_stamp; -* }wp_tx; -* unsigned char reserved[16]; -* }wp_tx_hdr_u; -* #define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp -* } wp_tdm_api_tx_hdr_t; -* -* typedef struct { -* wp_tdm_api_tx_hdr_t hdr; -* unsigned char data[1]; -* } wp_tdm_api_tx_element_t; -* -* #define WPTDM_A_BIT 0x08 -* #define WPTDM_B_BIT 0x04 -* #define WPTDM_C_BIT 0x02 -* #define WPTDM_D_BIT 0x01 -* -*/ - -void handle_span_chan(void) -{ - unsigned int Rx_count,Tx_count,Tx_length; - wp_tdm_api_rx_element_t* api_rx_el; - wp_tdm_api_tx_element_t * api_tx_el; - fd_set ready,write,oob; - int err,i; - -#if 0 - int rlen; - int stream_sync=0; -#endif - - Rx_count = 0; - Tx_count = 0; - - if (tdm_api.wp_tdm_cmd.hdlc) { - Tx_length = tx_size; - } else { - Tx_length = tdm_api.wp_tdm_cmd.usr_mtu_mru; - } - - printf("\n\nSocket Handler: Rx=%d Tx=%i TxCnt=%i TxLen=%i TxDelay=%i\n", - read_enable,write_enable,tx_cnt,tx_size,tx_delay); - - /* Initialize the Tx Data buffer */ - memset(&Tx_data[0],0,MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)); - - /* Cast the Tx data packet with the tx element - * structure. We must insert a 16 byte - * driver header, which driver will remove - * before passing packet out the physical port */ - api_tx_el = (wp_tdm_api_tx_element_t*)&Tx_data[0]; - - - /* Create a Tx packet based on user info, or - * by deafult incrementing number starting from 0 */ - for (i=0;idata[i] = (unsigned char)i; - }else{ -#if 0 - api_tx_el->data[i] = (unsigned char)tx_data+(i%4); -#else - api_tx_el->data[i] = (unsigned char)tx_data; -#endif - } - } - - sangoma_tdm_enable_rxhook_events(dev_fd, &tdm_api); - - /* Main Rx Tx OOB routine */ - for(;;) { - - /* Initialize all select() descriptors */ - FD_ZERO(&ready); - FD_ZERO(&write); - FD_ZERO(&oob); - FD_SET(dev_fd,&oob); - FD_SET(dev_fd,&ready); - - if (write_enable){ - FD_SET(dev_fd,&write); - } - - /* Select will block, until: - * 1: OOB event, link level change - * 2: Rx data available - * 3: Interface able to Tx */ - - if(select(dev_fd + 1,&ready, &write, &oob, NULL)){ - - fflush(stdout); - if (FD_ISSET(dev_fd,&oob)){ - - /* An OOB event is pending, usually indicating - * a link level change */ - - err=sangoma_tdm_read_event(dev_fd,&tdm_api); - - if(err < 0 ) { - printf("Failed to receive OOB %i , %i\n", Rx_count, err); - err = ioctl(dev_fd,SIOC_WANPIPE_SOCK_STATE,0); - printf("Sock state is %s\n", - (err == 0) ? "CONNECTED" : - (err == 1) ? "DISCONNECTED" : - "CONNECTING"); - break; - } - - printf("GOT OOB EXCEPTION CMD Exiting\n"); - } - - - if (FD_ISSET(dev_fd,&ready)){ - - /* An Rx packet is pending - * 1: Read the rx packet into the Rx_data - * buffer. Confirm len > 0 - * - * 2: Cast Rx_data to the api_rx_element. - * Thus, removing a 16 byte header - * attached by the driver. - * - * 3. Check error_flag: - * CRC,Abort..etc - */ - - memset(Rx_data, 0, sizeof(Rx_data)); - - err = sangoma_readmsg_tdm(dev_fd, - Rx_data, - sizeof(wp_tdm_api_rx_hdr_t), - &Rx_data[sizeof(wp_tdm_api_rx_hdr_t)], - MAX_RX_DATA, 0); - - - if (!read_enable){ - goto bitstrm_skip_read; - } - - /* err indicates bytes received */ - if(err <= 0) { - printf("\nError receiving data\n"); - break; - } - - api_rx_el = (wp_tdm_api_rx_element_t*)&Rx_data[0]; - - /* Check the packet length */ - Rx_lgth = err; - if(Rx_lgth<=0) { - printf("\nShort frame received (%d)\n", - Rx_lgth); - return; - } - -#if 0 - if (api_rx_el->data[0] == tx_data && api_rx_el->data[1] == (tx_data+1)){ - if (!stream_sync){ - printf("GOT SYNC %x\n",api_rx_el->data[0]); - } - stream_sync=1; - }else{ - if (stream_sync){ - printf("OUT OF SYNC: %x\n",api_rx_el->data[0]); - } - } -#endif - - ++Rx_count; - - if (verbose){ -#if 0 - printf("Received %i Length = %i\n", - Rx_count,Rx_lgth); - - printf("Data: "); - for(i=0;idata[i]); - } - printf("\n"); -#endif - }else{ - //putchar('R'); - } - - -#if 0 - switch(api_rx_el->hdr.wp_api_event_type){ - case WP_TDM_EVENT_DTMF: - printf("DTMV Event: %c (%s:%s)!\n", - api_rx_el->hdr.wp_api_event_dtmf_digit, - (api_rx_el->hdr.wp_api_event_dtmf_type&WP_TDM_EVENT_DTMF_ROUT)?"ROUT":"SOUT", - (api_rx_el->hdr.wp_api_event_dtmf_type&WP_TDM_EVENT_DTMF_PRESET)?"PRESET":"STOP"); - break; - case WP_TDM_EVENT_RXHOOK: - printf("RXHOOK Event: %s!\n", - (api_rx_el->hdr.wp_api_event_rxhook_state&WP_TDM_EVENT_RXHOOK_OFF)?"OFF-HOOK":"ON-HOOK"); - break; - case WP_TDM_EVENT_RING: - printf("RING Event: %s!\n", - (api_rx_el->hdr.wp_api_event_ring_state&WP_TDM_EVENT_RING_PRESENT)?"PRESENT":"STOP"); - break; - } -#endif - - if (rx_cnt > 0 && Rx_count >= rx_cnt){ - break; - } -bitstrm_skip_read: -; - } - - if (FD_ISSET(dev_fd,&write)){ - - - err = sangoma_writemsg_tdm(dev_fd, - Tx_data,16, - &Tx_data[16], Tx_length, - 0); - if (err <= 0){ - if (errno == EBUSY){ - if (verbose){ - printf("Sock busy try again!\n"); - } - /* Socket busy try sending again !*/ - }else{ - printf("Faild to send %i \n",errno); - perror("Send: "); - break; - } - }else{ - - ++Tx_count; - - if (verbose){ - //printf("Packet sent: Sent %i : %i\n", - // err,Tx_count); - }else{ - //putchar('T'); - } - } - } - - if (tx_delay){ - usleep(tx_delay); - } - - if (tx_cnt && tx_size && Tx_count >= tx_cnt && !(files_used & TX_FILE_USED)){ - - write_enable=0; - if (rx_cnt > 0){ - /* Dont break let rx finish */ - }else{ - break; - } - } - } - } - - sangoma_tdm_disable_rxhook_events(dev_fd, &tdm_api); - if (tx_fd){ - fclose(tx_fd); - } - if (rx_fd){ - fclose(rx_fd); - } - close (dev_fd); - return; - -} - -int rxhook_event (int fd, unsigned char state) -{ - printf("%d: RXHOOK Event: %s!\n", - fd, (state & WAN_EVENT_RXHOOK_OFF)?"OFF-HOOK":"ON-HOOK"); - return 0; -} - -/*************************************************************** - * Main: - * - * o Make a socket connection to the driver. - * o Call handle_span_chan() to read the socket - * - **************************************************************/ - - -int main(int argc, char* argv[]) -{ - int proceed; - - proceed=init_args(argc,argv); - if (proceed != WAN_TRUE){ - usage(argv[0]); - return -1; - } - - signal(SIGINT,&sig_end); - memset(&tdm_api,0,sizeof(tdm_api)); - tdm_api.wp_tdm_event.wp_rxhook_event = &rxhook_event; - - printf("TDM RXHOOK PTR = %p\n",tdm_api.wp_tdm_event.wp_rxhook_event); - - dev_fd =-1; - - dev_fd = sangoma_open_tdmapi_span_chan(atoi(card_name),atoi(if_name)); - if( dev_fd < 0){ - printf("Failed to open span chan (%s:%s:%d:%d)\n", - card_name, if_name, - atoi(card_name),atoi(if_name)); - exit (1); - } - printf("HANDLING SPAN %i CHAN %i FD=%i\n", - atoi(card_name),atoi(if_name),dev_fd); - - sangoma_tdm_set_codec(dev_fd,&tdm_api,WP_NONE); - sangoma_get_full_cfg(dev_fd, &tdm_api); - - handle_span_chan(); - close(dev_fd); - return 0; - - return 0; -}; - - -void sig_end(int sigid) -{ - - printf("Got Signal %i\n",sigid); - - sangoma_tdm_disable_rxhook_events(dev_fd, &tdm_api); - - if (tx_fd){ - fclose(tx_fd); - } - if (rx_fd){ - fclose(rx_fd); - } - - if (dev_fd){ - close (dev_fd); - } - - - exit(1); -} - - - diff --git a/api/wanec_apilib b/api/wanec_apilib new file mode 120000 index 0000000..bab9de0 --- /dev/null +++ b/api/wanec_apilib @@ -0,0 +1 @@ +../util/wanec_apilib \ No newline at end of file diff --git a/deb_control/wanpipe.deb b/deb_control/wanpipe.deb index 8ca4f4c..ec4db6a 100644 --- a/deb_control/wanpipe.deb +++ b/deb_control/wanpipe.deb @@ -1,5 +1,5 @@ Package: wanpipe -Version: 3.2.1-0 +Version: 3.2.2-0 Section: networking Priority: optional Architecture: all diff --git a/kbuild/Makefile b/kbuild/Makefile index 63ef945..78658c4 100644 --- a/kbuild/Makefile +++ b/kbuild/Makefile @@ -12,6 +12,7 @@ MODULE_NAME = EXTRA_CFLAGS = KDIR = $(MODULE_NAME)-objs = $(OBJS) +SUBDIRS=$(PWD) RM = @rm -rf JUNK = *~ *.bak DEADJOE @@ -29,16 +30,16 @@ PWD := $(shell pwd) KBUILD_VERBOSE= all: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules clean: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) clean distclean: clean $(RM) $(JUNK) $(OBJS) help: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) help + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) help # Indents the kernel source the way linux/Documentation/CodingStyle.txt @@ -47,6 +48,6 @@ indent: indent -kr -i8 $($(MODULE_NAME)-objs:.o=.c) install: - $(MAKE) -C $(KDIR) M=$(PWD) modules_install + $(MAKE) -C $(KDIR) M=$(SUBDIRS) modules_install endif diff --git a/kbuild/Makefile.wanec b/kbuild/Makefile.wanec index 8a77357..b88a52f 100644 --- a/kbuild/Makefile.wanec +++ b/kbuild/Makefile.wanec @@ -16,6 +16,8 @@ $(MODULE_NAME)-objs = $(OBJS) RM = @rm -rf JUNK = *~ *.bak DEADJOE +PWD := $(shell pwd) +SUBDIRS=$(PWD) # First pass, kernel Makefile reads module objects ifneq ($(KERNELRELEASE),) @@ -29,19 +31,19 @@ PWD := $(shell pwd) KBUILD_VERBOSE= all: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules clean: - $(shell find . -name '*.*o' | xargs rm) - $(shell find . -name '.*.o.cmd' | xargs rm) + $(shell find $(SUBDIRS) -name '*.*o' | xargs rm) + $(shell find $(SUBDIRS) -name '.*.o.cmd' | xargs rm) $(shell rm -f build.sh) - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) clean distclean: clean $(RM) $(JUNK) $(OBJS) help: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) help + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) help # Indents the kernel source the way linux/Documentation/CodingStyle.txt @@ -50,6 +52,6 @@ indent: indent -kr -i8 $($(MODULE_NAME)-objs:.o=.c) install: - $(MAKE) -C $(KDIR) M=$(PWD) modules_install + $(MAKE) -C $(KDIR) M=$(SUBDIRS) modules_install endif diff --git a/patches/copy_modules.sh b/patches/copy_modules.sh new file mode 100755 index 0000000..bd9d3a2 --- /dev/null +++ b/patches/copy_modules.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +from=$1 +to=$2 +echo "Coping $from to $to" + +eval "cp $(find $from -name '*.ko' | xargs) $to" +exit $? diff --git a/patches/kdrivers/include/sdla_aft_te1.h b/patches/kdrivers/include/sdla_aft_te1.h index 72ca904..b6b27bd 100644 --- a/patches/kdrivers/include/sdla_aft_te1.h +++ b/patches/kdrivers/include/sdla_aft_te1.h @@ -734,7 +734,7 @@ aft_dmachain_enable_tdmv_and_mtu_size(u32 *reg, int size) # define AFT_TXDMA_LO_ALIGN_MASK 0x03 # define AFT_TXDMA_LO_ALIGN_SHIFT 0 -# define AFT_TXDMA_HI_DMA_LENGTH_MASK 0x3FF +# define AFT_TXDMA_HI_DMA_LENGTH_MASK 0xFFF # define AFT_TXDMA_HI_DMA_LENGTH_SHIFT 0 # define AFT_TXDMA_HI_DMA_STATUS_MASK 0x0F @@ -759,7 +759,7 @@ aft_dmachain_enable_tdmv_and_mtu_size(u32 *reg, int size) # define AFT_RXDMA_LO_ALIGN_MASK 0x03 # define AFT_RXDMA_LO_ALIGN_SHIFT 0 -# define AFT_RXDMA_HI_DMA_LENGTH_MASK 0x3FF +# define AFT_RXDMA_HI_DMA_LENGTH_MASK 0xFFF # define AFT_RXDMA_HI_DMA_LENGTH_SHIFT 0 # define AFT_RXDMA_HI_DMA_STATUS_MASK 0x0F @@ -962,17 +962,17 @@ enum { static __inline unsigned short aft_valid_mtu(unsigned short mtu) { if (mtu <= 128){ - return 128; - }else if (mtu <= 256){ return 256; - }else if (mtu <= 512){ + }else if (mtu <= 256){ return 512; - }else if (mtu <= 1024){ + }else if (mtu <= 512){ return 1024; - }else if (mtu <= 2048){ + }else if (mtu <= 1024){ return 2048; - }else if (mtu <= 4096){ + }else if (mtu <= 2048){ return 4096; + }else if (mtu <= 4096){ + return 8188; }else if (mtu <= 8188){ return 8188; }else{ diff --git a/patches/kdrivers/include/sdla_front_end.h b/patches/kdrivers/include/sdla_front_end.h index 75864b0..17aa381 100644 --- a/patches/kdrivers/include/sdla_front_end.h +++ b/patches/kdrivers/include/sdla_front_end.h @@ -88,8 +88,10 @@ #define WAN_FE_ALARM_NONE 0x00 #define WAN_FE_ALARM_READ 0x01 #define WAN_FE_ALARM_PRINT 0x02 +#define WAN_FE_ALARM_UPDATE 0x04 #define IS_FE_ALARM_READ(action) ((action) & WAN_FE_ALARM_READ) #define IS_FE_ALARM_PRINT(action) ((action) & WAN_FE_ALARM_PRINT) +#define IS_FE_ALARM_UPDATE(action) ((action) & WAN_FE_ALARM_UPDATE) /* Read pmon flag */ #define WAN_FE_PMON_UPDATE 0x01 @@ -385,6 +387,7 @@ typedef struct sdla_fe_timer_event_ { WAN_LIST_ENTRY(sdla_fe_timer_event_) next; } sdla_fe_timer_event_t; +#define WAN_FE_MAX_QEVENT_LEN 20 typedef struct { char *name; void *card; @@ -412,6 +415,7 @@ typedef struct { wan_spinlock_t lock; wan_timer_t timer; WAN_LIST_HEAD(, sdla_fe_timer_event_) event; + unsigned int event_map; int (*write_cpld)(void*, unsigned short, unsigned char); int (*read_cpld)(void*, unsigned short, unsigned char); diff --git a/patches/kdrivers/include/sdla_te1.h b/patches/kdrivers/include/sdla_te1.h index b8da82c..bb91f17 100644 --- a/patches/kdrivers/include/sdla_te1.h +++ b/patches/kdrivers/include/sdla_te1.h @@ -147,6 +147,22 @@ #define WAN_T1_399_533 0x10 #define WAN_T1_533_655 0x11 +/* T1/E1: Recever */ +#define WAN_TE1_RX_SLEVEL_43_DB 430 /* 43 dB E1, RMONEN=0 */ +#define WAN_TE1_RX_SLEVEL_36_DB 360 /* 36 dB T1, RMONEN=0 */ +#define WAN_TE1_RX_SLEVEL_30_DB 300 /* 30 dB RMONEN=0 | 1 */ +#define WAN_TE1_RX_SLEVEL_225_DB 225 /* 22.5 dB RMONEN=1 */ +#define WAN_TE1_RX_SLEVEL_18_DB 180 /* 18 dB RMONEN=0 */ +#define WAN_TE1_RX_SLEVEL_175_DB 175 /* 17.5 dB RMONEN=1 */ +#define WAN_TE1_RX_SLEVEL_12_DB 120 /* 12 dB RMONEN=0 | 1 */ +#define WAN_TE1_RX_SLEVEL_DECODE(slevel) \ + ((slevel) == WAN_TE1_RX_SLEVEL_43_DB) ? "43dB" : \ + ((slevel) == WAN_TE1_RX_SLEVEL_36_DB) ? "36dB" : \ + ((slevel) == WAN_TE1_RX_SLEVEL_30_DB) ? "30dB" : \ + ((slevel) == WAN_TE1_RX_SLEVEL_225_DB) ? "22.5dB" : \ + ((slevel) == WAN_TE1_RX_SLEVEL_18_DB) ? "18dB" : \ + ((slevel) == WAN_TE1_RX_SLEVEL_175_DB) ? "17.5dB" : \ + ((slevel) == WAN_TE1_RX_SLEVEL_12_DB) ? "12dB" : "0dB" /* For T1 only (long or short haul) */ #define WAN_T1_LONG_HAUL 0x01 @@ -260,6 +276,7 @@ #define TE_POLL_CONFIG 0x0B #define TE_POLL_READ 0x0C #define TE_POLL_WRITE 0x0D +#define TE_LINKCRIT_TIMER 0x0F /* TE1 T1/E1 interrupt setting delay */ #define INTR_TE1_TIMER 150 /* 50 ms */ @@ -322,7 +339,7 @@ (FE_LBO(fe_cfg) == WAN_T1_133_266) ? "133-266ft" : \ (FE_LBO(fe_cfg) == WAN_T1_266_399) ? "266-399ft" : \ (FE_LBO(fe_cfg) == WAN_T1_399_533) ? "399-533ft" : \ - (FE_LBO(fe_cfg) == WAN_T1_533_655) ? "5330-599ft": \ + (FE_LBO(fe_cfg) == WAN_T1_533_655) ? "533-599ft": \ (FE_LBO(fe_cfg) == WAN_E1_120) ? "120OH" : \ (FE_LBO(fe_cfg) == WAN_E1_75) ? "75OH" : \ "Unknown" @@ -361,6 +378,7 @@ typedef struct sdla_te_cfg { u_int32_t active_ch; u_int32_t te_rbs_ch; u_int8_t high_impedance_mode; + int rx_slevel; u_int8_t te_ref_clock; u_int8_t sig_mode; } sdla_te_cfg_t; @@ -545,6 +563,8 @@ typedef struct { u_int16_t status_cnt; + wan_ticks_t crit_alarm_start; + unsigned int lb_mode; } sdla_te_param_t; diff --git a/patches/kdrivers/include/sdla_te1_ds.h b/patches/kdrivers/include/sdla_te1_ds.h index a2d1e9a..b5500f2 100644 --- a/patches/kdrivers/include/sdla_te1_ds.h +++ b/patches/kdrivers/include/sdla_te1_ds.h @@ -419,6 +419,16 @@ #define REG_RCICE4 0xD3 /* TX Framer Register Definitions */ +#define REG_E1TSACR 0x114 +#define BIT_E1TSACR_SiAF 0x80 +#define BIT_E1TSACR_SiNAF 0x40 +#define BIT_E1TSACR_RA 0x20 +#define BIT_E1TSACR_Sa4 0x10 +#define BIT_E1TSACR_Sa5 0x08 +#define BIT_E1TSACR_Sa6 0x04 +#define BIT_E1TSACR_Sa7 0x02 +#define BIT_E1TSACR_Sa8 0x01 + #define REG_SSIE1 0x118 #define BITS_SSIE1_ALL 0xFF #define BIT_SSIE1_CH1 0x80 @@ -495,6 +505,12 @@ #define REG_E1TNAF 0x165 +#define REG_E1TSa4 0x169 +#define REG_E1TSa5 0x16A +#define REG_E1TSa6 0x16B +#define REG_E1TSa7 0x16C +#define REG_E1TSa8 0x16D + #define REG_TMMR 0x180 #define BIT_TMMR_FRM_EN 0x80 #define BIT_TMMR_INIT_DONE 0x40 diff --git a/patches/kdrivers/include/sdlasfm.h b/patches/kdrivers/include/sdlasfm.h index 3211edb..d31b513 100644 --- a/patches/kdrivers/include/sdlasfm.h +++ b/patches/kdrivers/include/sdlasfm.h @@ -312,8 +312,12 @@ typedef struct sfm /* SDLA firmware file structire */ (adptr_subtype == AFT_SUBTYPE_NORMAL) ? "" : \ (adptr_subtype == AFT_SUBTYPE_SHARK) ? "SHARK" : "" -#define AFT_PCIEXPRESS_DECODE(hwcard) \ - ((hwcard)->pci_bridge_dev) ? " PCI-Express" : "" +#define AFT_PCITYPE_DECODE(hwcard) \ + ((hwcard)->pci_bridge_dev) ? "PCIe" : "PCI" + +#define AFT_PCIEXPRESS_DECODE AFT_PCITYPE_DECODE + + #endif /* _SDLASFM_H */ diff --git a/patches/kdrivers/include/wanpipe.h b/patches/kdrivers/include/wanpipe.h index 27e92e0..bed3fac 100644 --- a/patches/kdrivers/include/wanpipe.h +++ b/patches/kdrivers/include/wanpipe.h @@ -915,6 +915,10 @@ typedef struct sdla u_long oerrors, ierrors; u_long opackets, ipackets; #endif /* __FreeBSD__ */ + + /* This value is used for detecting TDM Voice + * rsync timeout, it should be long */ + unsigned long rsync_timeout; } sdla_t; /****** Public Functions ****************************************************/ diff --git a/patches/kdrivers/include/wanpipe_cfg.h b/patches/kdrivers/include/wanpipe_cfg.h index 5d9a933..2706f5b 100644 --- a/patches/kdrivers/include/wanpipe_cfg.h +++ b/patches/kdrivers/include/wanpipe_cfg.h @@ -889,6 +889,7 @@ typedef struct wan_hwec_conf_ { unsigned int clk_src; /* Octasic Clock Source Port */ unsigned int persist_disable;/* HW EC Persist */ + unsigned int noise_reduction;/* Noise Reduction control */ } wan_hwec_conf_t; diff --git a/patches/kdrivers/include/wanpipe_common.h b/patches/kdrivers/include/wanpipe_common.h index c9a5e1f..2de5447 100644 --- a/patches/kdrivers/include/wanpipe_common.h +++ b/patches/kdrivers/include/wanpipe_common.h @@ -578,6 +578,7 @@ void wanpipe_debugging (void* data, int pending); #else void wanpipe_debugging (unsigned long data); #endif +static __inline int wan_skb_tailroom(void* skb); /**************************************************************************** ** I N L I N E F U N C T I O N S @@ -1417,7 +1418,7 @@ static __inline void wan_skb_copyback(void* skb, int off, int len, caddr_t cp) struct sk_buff* sk = (struct sk_buff*)skb; unsigned char* data = NULL; if (off == wan_skb_len(skb)){ - if (sk->tail + len > sk->end){ + if (len > wan_skb_tailroom(sk)){ DEBUG_EVENT("wan_skb_copyback: Internal Error (off=%d,len=%d,skb_len=%d)!\n", off, len, wan_skb_len(skb)); return; @@ -1458,7 +1459,7 @@ static __inline int wan_skb_copyback_user(void* skb, int off, int len, caddr_t c struct sk_buff* sk = (struct sk_buff*)skb; unsigned char* data = NULL; if (off == wan_skb_len(skb)){ - if (sk->tail + len > sk->end){ + if (len > wan_skb_tailroom(sk)) { DEBUG_EVENT("wan_skb_copyback_user: Internal Error (off=%d,len=%d,skb_len=%d)!\n", off, len, wan_skb_len(skb)); return -EINVAL; diff --git a/patches/kdrivers/include/wanpipe_common.h~ b/patches/kdrivers/include/wanpipe_common.h~ new file mode 100644 index 0000000..537771f --- /dev/null +++ b/patches/kdrivers/include/wanpipe_common.h~ @@ -0,0 +1,2431 @@ +/* + * Copyright (c) 2002 + * Alex Feldman . All rights reserved. + * + * $Id: wanpipe_common.h,v 1.175 2007/02/24 00:17:14 sangoma Exp $ + */ + +/**************************************************************************** + * wanpipe_common.h WANPIPE(tm) Multiprotocol WAN Link Driver. + * + * Author: Alex Feldman + * + * ========================================================================== + * July 17, 2002 Alex Feldman Initial Version + **************************************************************************** + */ + +#ifndef __WANPIPE_COMMON_H +# define __WANPIPE_COMMON_H + +#ifdef __LINUX__ +# include +#else +# include +#endif + +#ifdef WAN_DEBUG_MEM +extern atomic_t wan_debug_mem; +#endif + +/**************************************************************************** +** D E F I N E S +****************************************************************************/ +#ifndef NIPQUAD +# define NIPQUAD(addr) \ + ((unsigned char *)&addr)[0], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[3] +#endif + +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + +# define WAN_LIST_HEAD(name, type) LIST_HEAD(name, type) +# define WAN_LIST_HEAD_INITIALIZER(head) LIST_HEAD_INITIALIZER(head) +# define WAN_LIST_ENTRY(type) LIST_ENTRY(type) +# define WAN_LIST_EMPTY(head) LIST_EMPTY(head) +# define WAN_LIST_FIRST(head) LIST_FIRST(head) +# define WAN_LIST_FOREACH(var, head, field) LIST_FOREACH(var, head, field) +# define WAN_LIST_INIT(head) LIST_INIT(head) +# define WAN_LIST_INSERT_AFTER(listelm, elm, field) LIST_INSERT_AFTER(listelm, elm, field) +/*# define WAN_LIST_INSERT_BEFORE(listelm, elm, field) LIST_INSERT_BEFORE(listelm, elm, field)*/ +# define WAN_LIST_INSERT_HEAD(head, elm, field) LIST_INSERT_HEAD(head, elm, field) +# define WAN_LIST_NEXT(elm, field) LIST_NEXT(elm, field) +# define WAN_LIST_REMOVE(elm, field) LIST_REMOVE(elm, field) + +#elif defined(__SOLARIS__) + +/* ********* S O L A R I S *****************/ + +# define WAN_LIST_HEAD(name, type) struct name { struct type * lh_first; } +# define WAN_LIST_HEAD_INITIALIZER(head) { NULL } +# define WAN_LIST_ENTRY(type) struct { struct type *le_next; struct type **le_prev; } +# define WAN_LIST_FIRST(head) ((head)->lh_first) +# define WAN_LIST_END(head) NULL +# define WAN_LIST_EMPTY(head) (WAN_LIST_FIRST(head) == WAN_LIST_END(head)) +# define WAN_LIST_NEXT(elm, field) ((elm)->field.le_next) +# define WAN_LIST_FOREACH(var, head, field) for((var) = WAN_LIST_FIRST(head); \ + (var); \ + (var) = WAN_LIST_NEXT(var, field)) +# define WAN_LIST_INIT(head) do { WAN_LIST_FIRST(head) = NULL;}\ + while(0) + +#define WAN_LIST_INSERT_HEAD(head, elm, field) do { \ + if ((WAN_LIST_NEXT((elm), field) = WAN_LIST_FIRST((head))) != NULL) \ + WAN_LIST_FIRST((head))->field.le_prev = &WAN_LIST_NEXT((elm), field);\ + WAN_LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &WAN_LIST_FIRST((head)); \ +} while (0) +#define WAN_LIST_INSERT_AFTER(listelm, elm, field) do { \ + if ((WAN_LIST_NEXT((elm), field) = WAN_LIST_NEXT((listelm), field)) != NULL)\ + WAN_LIST_NEXT((listelm), field)->field.le_prev = \ + &WAN_LIST_NEXT((elm), field); \ + WAN_LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &WAN_LIST_NEXT((listelm), field); \ +} while (0) +#define WAN_LIST_REMOVE(elm, field) do { \ + if (WAN_LIST_NEXT((elm), field) != NULL) \ + WAN_LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = WAN_LIST_NEXT((elm), field); \ +} while (0) + + +#elif defined(__LINUX__) +/* ********* L I N U X *****************/ + +# define WAN_LIST_HEAD(name, type) struct name { struct type * lh_first; } +# define WAN_LIST_HEAD_INITIALIZER(head) { NULL } +# define WAN_LIST_ENTRY(type) struct { struct type *le_next; struct type **le_prev; } +# define WAN_LIST_FIRST(head) ((head)->lh_first) +# define WAN_LIST_END(head) NULL +# define WAN_LIST_EMPTY(head) (WAN_LIST_FIRST(head) == WAN_LIST_END(head)) +# define WAN_LIST_NEXT(elm, field) ((elm)->field.le_next) +# define WAN_LIST_FOREACH(var, head, field) for((var) = WAN_LIST_FIRST(head); \ + (var); \ + (var) = WAN_LIST_NEXT(var, field)) +# define WAN_LIST_INIT(head) do { WAN_LIST_FIRST(head) = NULL;}\ + while(0) + +#define WAN_LIST_INSERT_HEAD(head, elm, field) do { \ + if ((WAN_LIST_NEXT((elm), field) = WAN_LIST_FIRST((head))) != NULL) \ + WAN_LIST_FIRST((head))->field.le_prev = &WAN_LIST_NEXT((elm), field);\ + WAN_LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &WAN_LIST_FIRST((head)); \ +} while (0) +#define WAN_LIST_INSERT_AFTER(listelm, elm, field) do { \ + if ((WAN_LIST_NEXT((elm), field) = WAN_LIST_NEXT((listelm), field)) != NULL)\ + WAN_LIST_NEXT((listelm), field)->field.le_prev = \ + &WAN_LIST_NEXT((elm), field); \ + WAN_LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &WAN_LIST_NEXT((listelm), field); \ +} while (0) +#define WAN_LIST_REMOVE(elm, field) do { \ + if (WAN_LIST_NEXT((elm), field) != NULL) \ + WAN_LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = WAN_LIST_NEXT((elm), field); \ +} while (0) + +#else +# error "WAN_LISTx macros not supported yet!" +#endif + +#if defined(WAN_KERNEL) + +#if defined(__FreeBSD__) +# define WAN_TAILQ_FIRST(ifp) TAILQ_FIRST(&ifp->if_addrhead) +# define WAN_TAILQ_NEXT(ifa) TAILQ_NEXT(ifa, ifa_link) +#elif defined (__OpenBSD__) +# define WAN_TAILQ_FIRST(ifp) TAILQ_FIRST(&ifp->if_addrlist) +# define WAN_TAILQ_NEXT(ifa) TAILQ_NEXT(ifa, ifa_list) +#elif defined (__NetBSD__) +# define WAN_TAILQ_FIRST(ifp) TAILQ_FIRST(&ifp->if_addrlist) +# define WAN_TAILQ_NEXT(ifa) TAILQ_NEXT(ifa, ifa_list) +#elif defined(__LINUX__) +#elif defined(__SOLARIS__) +#elif defined(__WINDOWS__) +#else +# error "WAN_TAILQ_x macros doesn't supported yet!" +#endif + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# if defined(__FreeBSD__) +# define WAN_PKTATTR_DECL(pktattr) +# else +# define WAN_PKTATTR_DECL(pktattr) struct altq_pktattr pktattr +# endif +# define WAN_IFQ_SET_READY IFQ_SET_READY +# define WAN_IFQ_IS_EMPTY IFQ_IS_EMPTY +# define WAN_IFQ_INC_LEN IFQ_INC_LEN +# define WAN_IFQ_DEC_LEN IFQ_DEC_LEN +# define WAN_IFQ_INC_DROPS IFQ_INC_DROPS +# define WAN_IFQ_SET_MAXLEN IFQ_SET_MAXLEN +# define WAN_IFQ_PURGE IFQ_PURGE +# if (__FreeBSD_version > 503000) +# define WAN_IFQ_ENQUEUE(ifq, m, pattr, err) IFQ_ENQUEUE((ifq),(m),(err)) +# else +# define WAN_IFQ_ENQUEUE IFQ_ENQUEUE +# endif +# define WAN_IFQ_DEQUEUE IFQ_DEQUEUE +# define WAN_IFQ_POLL IFQ_POLL +# define WAN_IFQ_CLASSIFY IFQ_CLASSIFY +# define WAN_IFQ_INIT IFQ_INIT +# define WAN_IFQ_LEN IFQ_LEN +#elif defined(__LINUX__) +# define WAN_IFQ_INIT(ifq, max_pkt) skb_queue_head_init((ifq)) +# define WAN_IFQ_PURGE(ifq) skb_queue_purge((ifq)) +# define WAN_IFQ_ENQUEUE(ifq, skb, arg, err) skb_queue_tail((ifq), (skb)) +# define WAN_IFQ_LEN(ifq) skb_queue_len((ifq)) +#elif defined(__WINDOWS__) +#else +# error "Undefined IFQ_x macros!" +#endif + +#if defined(__FreeBSD__) +# if (__FreeBSD_version < 410000) +# define WAN_TASKLET_INIT(task, priority, func, arg) \ + (task)->running = 0; \ + (task)->task_func = func; (task)->data = arg +# define WAN_TASKLET_SCHEDULE(task) \ + if (!wan_test_bit(0, &(task)->running)){ \ + wan_set_bit(0, &(task)->running); \ + (task)->task_func((task)->data, 0); \ + } +# define __WAN_TASKLET_SCHEDULE(task) WAN_TASKLET_SCHEDULE(task) + +# define WAN_TASKLET_RUNNING(task) \ + wan_test_bit(0, &(task)->running) + +# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) +# define WAN_TASKLET_RUNNING(task) \ + wan_test_bit(0, &(task)->running) + +# define WAN_TASKLET_KILL(task) +# else +# define WAN_TASKLET_INIT(task, priority, func, arg) \ + (task)->running = 0; \ + TASK_INIT(&(task)->task_id, priority, func, (void*)arg) +# define WAN_TASKLET_SCHEDULE(task) \ + if (!wan_test_bit(0, &(task)->running)){ \ + wan_set_bit(0, &(task)->running); \ + taskqueue_enqueue(taskqueue_swi, &(task)->task_id); \ + } +# define __WAN_TASKLET_SCHEDULE(task) WAN_TASKLET_SCHEDULE(task) + +# define WAN_TASKLET_RUNNING(task) \ + wan_test_bit(0, &(task)->running) + +/* taskqueue_run(taskqueue_swi); \*/ +# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) +# define WAN_TASKLET_KILL(task) +# endif +#elif defined(__OpenBSD__) || defined(__NetBSD__) +# define WAN_TASKLET_INIT(task, priority, func, arg) \ + (task)->running = 0; \ + (task)->task_func = func; (task)->data = arg +# define WAN_TASKLET_SCHEDULE(task) \ + if (!wan_test_bit(0, &(task)->running)){ \ + wan_set_bit(0, &(task)->running); \ + (task)->task_func((task)->data, 0); \ + } + +# define __WAN_TASKLET_SCHEDULE(task) WAN_TASKLET_SCHEDULE(task) + +# define WAN_TASKLET_RUNNING(task) \ + wan_test_bit(0, &(task)->running) +# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) +# define WAN_TASKLET_KILL(task) + + +#elif defined(__LINUX__) + +# define WAN_TASKLET_INIT(task, priority, func, arg) \ + (task)->running = 0; \ + tasklet_init(&(task)->task_id,func,(unsigned long)arg) + +# define WAN_TASKLET_SCHEDULE(task) \ + wan_set_bit(0, &(task)->running); \ + tasklet_schedule(&(task)->task_id); + +#if 0 +# define WAN_WP_TASKLET_SCHEDULE_PER_CPU(task,cpu) \ + wan_set_bit(0, &(task)->running); \ + wp_tasklet_hi_schedule_per_cpu(&(task)->task_id,cpu); +#endif + +# define WAN_TASKLET_RUNNING(task) \ + wan_test_bit(0, &(task)->running) + +# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) +# define WAN_TASKLET_KILL(task) tasklet_kill(&(task)->task_id) + + +#elif defined(__WINDOWS__) +#else +# error "Undefined WAN_TASKLET_x macro!" +#endif + +#if defined(__FreeBSD__) +# if (__FreeBSD_version < 410000) +# define WAN_TASKQ_INIT(task, priority, func, arg) \ + (task)->tfunc = func; task->data = arg +# else +# define WAN_TASKQ_INIT(task, priority, func, arg) \ + TASK_INIT(&task->tqueue, priority, func, arg) +# endif +#elif defined(__OpenBSD__) +# define WAN_TASKQ_INIT(task, priority, func, arg) \ + (task)->tfunc = func; task->data = arg +#elif defined(__NetBSD__) +# define WAN_TASKQ_INIT(task, priority, func, arg) \ + (task)->tfunc = func; task->data = arg +#elif defined(__LINUX__) +/* Due to 2.6.20 kernel the wan_taskq_t is now a direct + * workqueue struct not an abstracted structure */ +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +# define WAN_TASKQ_INIT(task, priority, func, arg) \ + INIT_WORK((task),func,arg) +# else +# define WAN_TASKQ_INIT(task, priority, func, arg) \ + INIT_WORK((task),func) +# endif + +#elif defined(__WINDOWS__) +#else +# error "Undefined WAN_TASKQ_INIT macro!" +#endif + +#if defined(__FreeBSD__) && (__FreeBSD_version >= 410000) +# define WAN_IS_TASKQ_SCHEDULE +# define WAN_TASKQ_SCHEDULE(task) \ + taskqueue_enqueue(taskqueue_swi, &task->tqueue);\ + taskqueue_run(taskqueue_swi) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# define WAN_IS_TASKQ_SCHEDULE +# define WAN_TASKQ_SCHEDULE(task) \ + task->tfunc(task->data, 0) +#elif defined(__LINUX__) +# define WAN_IS_TASKQ_SCHEDULE +# define WAN_TASKQ_SCHEDULE(task) \ + wan_schedule_task(task) +#elif defined(__WINDOWS__) +#else +# error "Undefined WAN_TASKQ_SCHEDULE macro!" +#endif + +#if defined(__LINUX__) +# define WAN_COPY_FROM_USER(k,u,l) copy_from_user(k,u,l) +# define WAN_COPY_TO_USER(u,k,l) copy_to_user(u,k,l) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# define WAN_COPY_FROM_USER(k,u,l) copyin(u,k,l) +# define WAN_COPY_TO_USER(u,k,l) copyout(k,u,l) +#elif defined(__WINDOWS__) +#else +# error "Undefined WAN_COPY_FROM_USER/WAN_COPY_TO_USER macros!" +#endif + +#if defined(__LINUX__) +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) +# define WAN_NETIF_WAKE_QUEUE(dev) do { \ + clear_bit(0, &dev->tbusy); \ + mark_bh(NET_BH); \ + } while(0) +# define WAN_NETIF_START_QUEUE(dev) do { \ + dev->tbusy = 0; \ + dev->interrupt = 0; \ + dev->start = 1; \ + } while(0); +# define WAN_NETIF_STOP_QUEUE(dev) set_bit(0, &dev->tbusy) +# define WAN_NETIF_RUNNING(dev) dev->start +# define WAN_NETDEVICE_START(dev) dev->start = 1 +# define WAN_NETDEVICE_STOP(dev) dev->start = 0 +# define WAN_NETIF_QUEUE_STOPPED(dev) test_bit(0,&dev->tbusy) +# define WAN_NETIF_CARRIER_OFF(dev) +# define WAN_NETIF_CARRIER_ON(dev) +# define WAN_NETIF_CARRIER_OK(dev) 1 +# else +#if 0 +# define WAN_NETIF_WAKE_QUEUE(dev) do{ \ + if (((wanpipe_common_t *)dev->priv)->usedby == TDM_VOICE){ \ + DEBUG_EVENT("%s: TDM VOICE not waking but starting!!!!\n",dev->name); \ + netif_start_queue(dev); \ + }else{ \ + netif_wake_queue(dev); \ + } \ + }while(0) +#endif +# define WAN_NETIF_WAKE_QUEUE(dev) netif_wake_queue(dev); +# define WAN_NETIF_START_QUEUE(dev) netif_start_queue(dev) +# define WAN_NETIF_STOP_QUEUE(dev) netif_stop_queue(dev) +# define WAN_NETIF_RUNNING(dev) netif_running(dev) +# define WAN_NETDEVICE_START(dev) +# define WAN_NETDEVICE_STOP(dev) +# define WAN_NETIF_QUEUE_STOPPED(dev) netif_queue_stopped(dev) +# define WAN_NETIF_CARRIER_OFF(dev) netif_carrier_off(dev) +# define WAN_NETIF_CARRIER_ON(dev) netif_carrier_on(dev) +# define WAN_NETIF_CARRIER_OK(dev) netif_carrier_ok(dev) +# endif +# define WAN_NETIF_UP(dev) ((dev)->flags&IFF_UP) +# define WAN_NET_RATELIMIT net_ratelimit + +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# define WAN_NETIF_QUEUE_STOPPED(dev) (dev)->if_flags & IFF_DRV_OACTIVE +# define WAN_NETIF_WAKE_QUEUE(dev) (dev)->if_flags &= ~IFF_DRV_OACTIVE +#if 0 +# define WAN_NETIF_STOP_QUEUE(dev) +# define WAN_NETIF_START_QUEUE(dev) +#endif +# define WAN_NETIF_STOP_QUEUE(dev) (dev)->if_flags |= IFF_DRV_OACTIVE +# define WAN_NETIF_START_QUEUE(dev) (dev)->if_flags &= ~IFF_DRV_OACTIVE +# define WAN_NETIF_RUNNING(dev) 1 +# define WAN_NETIF_UP(dev) ((dev)->if_flags&IFF_UP) +# define WAN_NETDEVICE_STOP(dev) +# define WAN_NETDEVICE_START(dev) +# define NET_ADMIN_CHECK() +# define WAN_NET_RATELIMIT() 1 +# define MOD_INC_USE_COUNT +# define MOD_DEC_USE_COUNT + +# define WAN_NETIF_CARRIER_OFF(dev) +# define WAN_NETIF_CARRIER_ON(dev) +# define WAN_NETIF_CARRIER_OK(dev) 1 + +#elif defined(__WINDOWS__) +#else +# error "Undefined WAN_NETIF_x macros!" +#endif + +#if defined(__LINUX__) +# define WAN_BPF_DIR_IN (1<<0) +# define WAN_BPF_DIR_OUT (1<<1) +# define WAN_BPF_REPORT(dev,m) +#elif defined(__FreeBSD__) +# define WAN_BPF_DIR_IN (1<<0) +# define WAN_BPF_DIR_OUT (1<<1) +# if (__FreeBSD_version > 500000) +# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev)->if_bpf, (m)) +# else +# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev), (m)) +# endif +#elif defined(__OpenBSD__) +# if (OpenBSD < 200611) +# define WAN_BPF_DIR_IN (1<<0) +# define WAN_BPF_DIR_OUT (1<<1) +# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev)->if_bpf, (m)); +# else +# define WAN_BPF_DIR_IN BPF_DIRECTION_IN +# define WAN_BPF_DIR_OUT BPF_DIRECTION_OUT +# define WAN_BPF_REPORT(dev,m,d) \ + if (dir == WAN_BPF_DIR_IN){ \ + bpf_mtap((dev)->if_bpf, (m), BPF_DIRECTION_IN); \ + }else{ \ + bpf_mtap((dev)->if_bpf, (m), BPF_DIRECTION_OUT); \ + } +# endif +#elif defined(__NetBSD__) +# define WAN_BPF_DIR_IN (1<<0) +# define WAN_BPF_DIR_OUT (1<<1) +# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev)->if_bpf, (m)); +#elif defined(__WINDOWS__) +#else +# error "Undefined WAN_BPF_REPORT macro!" +#endif + + +#if defined (__LINUX__) +# define WAN_DEV_PUT(dev) wan_atomic_dec(&(dev)->refcnt) +# define WAN_DEV_HOLD(dev) wan_atomic_inc(&(dev)->refcnt) +# define __WAN_PUT(str) wan_atomic_dec(&(str)->refcnt) +# define WAN_PUT(str) if (atomic_dec_and_test(&(str)->refcnt)){ \ + wan_kfree(str); \ + } +# define WAN_HOLD(str) wan_atomic_inc(&(str)->refcnt) +#elif defined(__FreeBSD__) +# define WAN_DEV_PUT(dev) +# define WAN_DEV_HOLD(dev) +# define __WAN_PUT(str) wan_atomic_dec(&(str)->refcnt) +# define WAN_PUT(str) wan_atomic_dec(&str->refcnt); \ + if (str->refcnt){ \ + WAN_FREE(str); \ + } +# define WAN_HOLD(str) wan_atomic_inc(&(str)->refcnt) +#elif defined(__NetBSD__) || defined(__OpenBSD__) +# define WAN_DEV_PUT(dev) +# define WAN_DEV_HOLD(dev) +# define __WAN_PUT(str) str->refcnt-- +# define WAN_PUT(str) str->refcnt--; \ + if (str->refcnt){ \ + WAN_FREE(str); \ + } +# define WAN_HOLD(str) str->refcnt++ +#elif defined(__WINDOWS__) +#else +# warning "Undefined WAN_HOLD/WAN_PUT macro!" +#endif + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# ifdef ENABLE_SPPP +# define WAN_SPPP_ENABLED 1 +# define WAN_SPPP_ATTACH(ifp) sppp_attach(ifp) +# define WAN_SPPP_DETACH(ifp) sppp_detach(ifp) +# define WAN_SPPP_FLUSH(ifp) sppp_flush(ifp) +# define WAN_SPPP_PICK(ifp) sppp_pick(ifp) +# define WAN_SPPP_DEQUEUE(ifp) sppp_dequeue(ifp) +# define WAN_SPPP_ISEMPTY(ifp) sppp_isempty(ifp) +# define WAN_SPPP_INPUT(ifp,skb) sppp_input(ifp,skb) +# define WAN_SPPP_IOCTL(ifp,cmd,data) sppp_ioctl(ifp,cmd,data); +# else +# define WAN_SPPP_ENABLED 0 +# define WAN_SPPP_ATTACH(ifp) +# define WAN_SPPP_DETACH(ifp) +# define WAN_SPPP_FLUSH(ifp) +# define WAN_SPPP_PICK(ifp) NULL +# define WAN_SPPP_DEQUEUE(ifp) NULL +# define WAN_SPPP_ISEMPTY(ifp) 0 +# define WAN_SPPP_INPUT(ifp,skb) +# define WAN_SPPP_IOCTL(ifp,cmd,data) -EOPNOTSUPP +# endif +#elif defined(__LINUX__) +# define WAN_SPPP_ENABLED 1 +# define WAN_SPPP_IOCTL(ifp,cmd,data) -EOPNOTSUPP +#elif defined(__WINDOWS__) +#else +# error "Undefined WAN_SPPP_x macros!" +#endif + +#define WAN_MAX_TRACE_TIMEOUT (5*HZ) + +#if 0 +/* + * Variable argument list macro definitions + */ +#ifndef _VALIST +#define _VALIST +typedef char *va_list; +#endif /* _VALIST */ +#define _WAN_VA_SIZE(type) (((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long)) + +#define WAN_VA_START(ap, A) ((ap) = (va_list) &(A) + _WAN_VA_SIZE(A)) +#define WAN_VA_ARG(ap, T) (*(T *)((ap) += _WAN_VA_SIZE(T),(ap) - _WAN_VA_SIZE (T))) +#define WAN_VA_END(ap) (void) 0 +#endif + + +/**************************************************************************** +** T Y P E D E F S +****************************************************************************/ +# if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +/* + * Ethernet statistics collection data + */ +struct net_device_stats +{ + unsigned long rx_packets; /* total packets received */ + unsigned long tx_packets; /* total packets transmited */ + unsigned long rx_bytes; /* total bytes received */ + unsigned long tx_bytes; /* total bytes transmited */ + unsigned long rx_errors; /* bad packet received */ + unsigned long tx_errors; /* packet transmit problems */ + unsigned long rx_dropped; /* no space in buffers */ + unsigned long tx_dropped; /* no space available */ + unsigned long multicast; /* multicast packet received */ + unsigned long collisions; + + /* detailed rx_errors */ + unsigned long rx_length_errors; + unsigned long rx_over_errors; /* receiver ring off buff overflow */ + unsigned long rx_crc_errors; /* recv'd pkt with crc error */ + unsigned long rx_frame_errors; /* recv'd frame alignment error */ + unsigned long rx_fifo_errors; /* recv'r fifo overrun */ + unsigned long rx_missed_errors; /* receiver missed packet */ + + /* detailed tx_errors */ + unsigned long tx_aborted_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; + unsigned long tx_heartbeat_errors; + unsigned long tx_window_errors; + + /* for cslip etc */ + unsigned long rx_compressed; + unsigned long tx_compressed; +}; +#endif + +/**************************************************************************** +** F U N C T I O N P R O T O T Y P E S +****************************************************************************/ +unsigned int wan_dec2uint (unsigned char* str, int len); +char* wanpipe_get_state_string (void*); +void wanpipe_set_state (void*, int); +char wanpipe_get_state (void*); +void wanpipe_card_lock_irq (void *,unsigned long *); +void wanpipe_card_unlock_irq (void *,unsigned long *); +void wanpipe_set_baud(void*card,unsigned int baud); +unsigned long wan_get_ip_addr (void*, int); +int wan_udp_pkt_type (void*, caddr_t); +int wan_reply_udp (void*, unsigned char*, unsigned int); +unsigned short wan_calc_checksum(char *data, int len); +void wanpipe_debug_timer_init(void*); +void wan_trace_info_init(wan_trace_t *trace, int max_trace_queue); +int wan_trace_purge (wan_trace_t *trace); +int wan_trace_enqueue(wan_trace_t *trace, void *skb_ptr); +int wan_tracing_enabled(wan_trace_t *trace_info); +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +void wanpipe_debugging (void* data, int pending); +#else +void wanpipe_debugging (unsigned long data); +#endif + +/**************************************************************************** +** I N L I N E F U N C T I O N S +****************************************************************************/ +/******************* WANPIPE MALLOC/FREE FUNCTION ******************/ +/* +** wan_malloc - +*/ +static __inline void* wan_malloc(int size) +{ + void* ptr = NULL; +#if defined(__LINUX__) + ptr = kmalloc(size, GFP_ATOMIC); + if (ptr){ + DEBUG_ADD_MEM(size); + } +#elif defined(__SOLARIS__) + ptr=kmem_alloc(size,KM_NOSLEEP); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + ptr = malloc(size, M_DEVBUF, M_NOWAIT); +#elif defined(__WINDOWS__) + ptr = ExAllocatePool(NonPagedPool, size); +#else +# error "wan_malloc() function is not supported yet!" +#endif + if (ptr){ + memset(ptr, 0, size); + DEBUG_ADD_MEM(size); + } + return ptr; +} + +static __inline void* wan_kmalloc(int size) +{ + void* ptr = NULL; +#if defined(__LINUX__) + ptr = kmalloc(size, GFP_KERNEL); + if (ptr){ + DEBUG_ADD_MEM(size); + } +#elif defined(__SOLARIS__) + ptr=kmem_alloc(size,KM_NOSLEEP); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + ptr = malloc(size, M_DEVBUF, M_NOWAIT); +#elif defined(__WINDOWS__) + ptr = ExAllocatePool(NonPagedPool, size); +#else +# error "wan_malloc() function is not supported yet!" +#endif + if (ptr){ + memset(ptr, 0, size); + DEBUG_ADD_MEM(size); + } + return ptr; +} + +/* +** wan_free - +*/ +static __inline void wan_free(void* ptr) +{ + if (!ptr){ + DEBUG_EVENT("wan_free: NULL PTR !!!!!\n"); + return; + } + +#if defined(__LINUX__) + kfree(ptr); +#elif defined(__SOLARIS__) + kmem_free(ptr,sizeof(*ptr)); + DEBUG_EVENT("%s: Feeing Size %i\n",__FUNCTION__,sizeof(*ptr)); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + return free(ptr, M_DEVBUF); +#elif defined(__WINDOWS__) + ExFreePool(ptr); +#else +# error "wan_free() function is not supported yet!" +#endif +} + +static __inline void* wan_vmalloc(int size) +{ + void* ptr = NULL; +#if defined(__LINUX__) + ptr = vmalloc(size); + if (ptr){ + DEBUG_ADD_MEM(size); + } +#elif defined(__FreeBSD__) + ptr = (caddr_t)kmem_alloc(kernel_map, size + sizeof(vm_size_t)); + if (ptr){ + vm_size_t *ptr1 = (vm_size_t*)ptr; + bzero(ptr, size); + *ptr1 = size + sizeof(vm_size_t); + ptr = ptr1++; + } +#elif defined(__OpenBSD__) || defined(__NetBSD__) + ptr = (caddr_t)uvm_km_alloc(kernel_map, size + sizeof(vsize_t)); + if (ptr){ + vsize_t *ptr1 = (vsize_t*)ptr; + bzero(ptr, size); + *ptr1 = size + sizeof(vsize_t); + ptr = ptr1++; + } +#elif defined(__SOLARIS__) +#elif defined(__WINDOWS__) +#else +# error "wan_vmalloc() function is not supported yet!" +#endif + if (ptr){ + memset(ptr, 0, size); + DEBUG_ADD_MEM(size); + } + return ptr; +} + +/* +** wan_vfree - +*/ +static __inline void wan_vfree(void* ptr) +{ + if (!ptr){ + DEBUG_EVENT("wan_vfree: NULL PTR !!!!!\n"); + return; + } +#if defined(__LINUX__) + vfree(ptr); +#elif defined(__FreeBSD__) + { + vm_size_t *ptr1 = (vm_size_t*)ptr; + ptr1 --; + kmem_free(kernel_map, (vm_offset_t)ptr1, (vm_size_t)*ptr1); + } +#elif defined(__OpenBSD__) || defined(__NetBSD__) + { + vsize_t *ptr1 = (vsize_t*)ptr; + ptr1 --; + uvm_km_free(kernel_map, (vaddr_t)ptr1, (vsize_t)*ptr1); + } +#elif defined(__SOLARIS__) +#elif defined(__WINDOWS__) +#else +# error "wan_free() function is not supported yet!" +#endif + return; +} + + +/******************* WANPIPE VIRT<->BUS SPACE FUNCTION ******************/ +/* +** wan_virt2bus +*/ +static __inline unsigned long wan_virt2bus(unsigned long* ptr) +{ +#if defined(__LINUX__) + return virt_to_bus(ptr); +#elif defined(__FreeBSD__) + return vtophys((vm_offset_t)ptr); +#elif defined(__OpenBSD__) || defined(__NetBSD__) + return vtophys((vaddr_t)ptr); +#elif defined(__WINDOWS__) +#else +# error "wan_virt2bus() function is not supported yet!" +#endif +} + +/* +** wan_bus2virt +*/ +static __inline unsigned long* wan_bus2virt(unsigned long virt_addr) +{ +#if defined(__LINUX__) + return bus_to_virt(virt_addr); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + return (unsigned long*)virt_addr; +#elif defined(__WINDOWS__) +#else +# error "wan_bus2virt() function is not supported yet!" +#endif +} + + +/******************* WANPIPE DMA FUNCTION ******************/ + +/* +** wan_dma_alloc +*/ +static __inline int +wan_dma_alloc(void* hw, wan_dma_descr_t* dma_descr) +{ + int err = 0; +#if defined(__FreeBSD__) + err = bus_dma_tag_create(/*parent*/NULL, + /*alignemnt*/1, + /*boundary*/0, + /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*highaddr*/BUS_SPACE_MAXADDR, + /*filter*/NULL, /*filterarg*/NULL, + /*maxsize*/dma_descr->max_length, +# if (__FreeBSD_version >= 502000) + /*nsegments*/1, +# else + /*nsegments*/BUS_SPACE_UNRESTRICTED, +# endif + /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, + /*flags*/0, +# if (__FreeBSD_version >= 502000) + /*lockfunc*/NULL, /*lockfuncarg*/NULL, +# endif + &dma_descr->dmat); + if (err){ + DEBUG_EVENT("Failed create DMA tag (size=%ld)!\n", + dma_descr->max_length); + dma_descr->max_length = 0; + return err; + } + err = bus_dmamem_alloc(dma_descr->dmat, + (void**)&dma_descr->vAddr, + BUS_DMA_NOWAIT, + &dma_descr->dmamap); + if (err){ + DEBUG_EVENT("Failed allocate DMA (size=%ld)!\n", + dma_descr->max_length); + bus_dma_tag_destroy(dma_descr->dmat); + dma_descr->max_length = 0; + return err; + } +#elif defined(__OpenBSD__) || defined(__NetBSD__) + err = bus_dmamem_alloc(dma_descr->dmat, /* dma tag */ + dma_descr->max_length, /* size */ + PAGE_SIZE, /* alignment */ + 0, /* boundary */ + &dma_descr->dmaseg, /* serments */ + 1, /* num of segments */ + &dma_descr->rsegs, /* R num of segments */ + BUS_DMA_NOWAIT); + if (err){ + DEBUG_EVENT("Failed allocate DMA segment (size=%ld)!\n", + dma_descr->max_length); + dma_descr->max_length = 0; + return err; + } + err = bus_dmamem_map(dma_descr->dmat, /* dma tag */ + &dma_descr->dmaseg, /* segments */ + dma_descr->rsegs, /* return num of segments */ + dma_descr->max_length, /* size */ + (caddr_t*)&dma_descr->vAddr, /* kernel virtual address */ + BUS_DMA_NOWAIT); + if (err){ + DEBUG_EVENT("Failed map DMA segment (size=%ld)!\n", + dma_descr->max_length); + dma_descr->max_length = 0; + bus_dmamem_free(dma_descr->dmat, &dma_descr->dmaseg, dma_descr->rsegs); + return err; + } +#elif defined(__LINUX__) + dma_descr->vAddr = pci_alloc_consistent(NULL, + dma_descr->max_length, + (dma_addr_t *)&dma_descr->pAddr); + if (dma_descr->vAddr == NULL){ + err = -ENOMEM; + } +#elif defined(__WINDOWS__) + return -EINVAL; +#else +# error "wan_dma_alloc() function is not supported yet!" +#endif + return err; +} + +/* +** wan_dma_free +*/ +static __inline int +wan_dma_free(void* hw, wan_dma_descr_t* dma_descr) +{ +#if defined(__FreeBSD__) + bus_dmamem_free(dma_descr->dmat, dma_descr->vAddr, dma_descr->dmamap); + return bus_dma_tag_destroy(dma_descr->dmat); +#elif defined(__OpenBSD__) || defined(__NetBSD__) + bus_dmamem_unmap(dma_descr->dmat, (caddr_t)dma_descr->vAddr, dma_descr->max_length); + bus_dmamem_free(dma_descr->dmat, &dma_descr->dmaseg, dma_descr->rsegs); +#elif defined(__LINUX__) + + DEBUG_TEST("Freeing Pages 0x%p len=%li order=%i\n", + dma_descr->vAddr, + dma_descr->max_length, + get_order(dma_descr->max_length)); + + pci_free_consistent(NULL, dma_descr->max_length,dma_descr->vAddr,dma_descr->pAddr); + dma_descr->vAddr = NULL; + dma_descr->pAddr = 0; +#elif defined(__WINDOWS__) + return -EINVAL; +#else +# error "wan_dma_free() function is not supported yet!" +#endif + return 0; +} + +static __inline unsigned long* wan_dma_get_vaddr(void* card, wan_dma_descr_t* dma) +{ + return dma->vAddr; +} + +static __inline unsigned long wan_dma_get_paddr(void* card, wan_dma_descr_t* dma) +{ + return wan_virt2bus(dma->vAddr); +} + + + + + +/********************** WANPIPE TIMER FUNCTION **************************/ + + +static __inline int wan_getcurrenttime(unsigned long *sec, unsigned long *usec) +{ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct timeval tv; + microtime(&tv); + if (sec) *sec = tv.tv_sec; + if (usec) *usec = tv.tv_usec; + return 0; +#elif defined(__WINDOWS__) + LARGE_INTEGER tv; + NdisGetCurrentSystemTime(&tv); + if (sec) *sec = (unsigned long)tv.QuadPart; + return 0; +#elif defined(__LINUX__) + struct timeval tv; + do_gettimeofday(&tv); + if (sec) *sec = tv.tv_sec; + if (usec) *usec = tv.tv_usec; + return 0; +#else +# error "wan_getcurrenttime() function is not supported yet!" +#endif +} + +/* +** wan_init_timer +*/ +static __inline void +wan_init_timer(wan_timer_t* wan_timer, wan_timer_func_t timer_func, wan_timer_arg_t arg) +{ +#if defined(__LINUX__) + init_timer(&wan_timer->timer_info); + wan_timer->timer_info.function = timer_func; + wan_timer->timer_info.data = arg; +#elif defined(__FreeBSD__) + /* FIXME_ADSL_TIMER */ + callout_handle_init(&wan_timer->timer_info); + wan_timer->timer_func = timer_func; + wan_timer->timer_arg = arg; +#elif defined(__OpenBSD__) + timeout_set(&wan_timer->timer_info, timer_func, (void*)arg); + wan_timer->timer_func = timer_func; + wan_timer->timer_arg = arg; +#elif defined(__NetBSD__) + callout_init(&wan_timer->timer_info); + wan_timer->timer_func = timer_func; + wan_timer->timer_arg = arg; +#elif defined(__WINDOWS__) +#else +# error "wan_init_timer() function is not supported yet!" +#endif /* linux */ +} + +/* +** wan_del_timer +*/ +static __inline void +wan_del_timer(wan_timer_t* wan_timer) +{ +#if defined(__LINUX__) + if (!wan_timer->timer_info.function){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%d Warning: WAN Timer del error: func=%p\n", + __FUNCTION__,__LINE__, + wan_timer->timer_info.function); + } + return; + } + del_timer(&wan_timer->timer_info); +#elif defined(__FreeBSD__) + untimeout(wan_timer->timer_func, + (void*)wan_timer->timer_arg, + wan_timer->timer_info); + callout_handle_init(&wan_timer->timer_info); +#elif defined(__OpenBSD__) + timeout_del(&wan_timer->timer_info); +#elif defined(__NetBSD__) + callout_stop(&wan_timer->timer_info); +#else +# error "wan_del_timer() function is not supported yet!" +#endif /* linux */ +} + +/* +** wan_add_timer +*/ +static __inline int +wan_add_timer(wan_timer_t* wan_timer, unsigned long delay) +{ +#if defined(__LINUX__) + if (timer_pending(&wan_timer->timer_info) || + !wan_timer->timer_info.function){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%d Warning: WAN Timer add error: pending or func=%p\n", + __FUNCTION__,__LINE__, + wan_timer->timer_info.function); + } + return -EINVAL; + } + wan_timer->timer_info.expires = SYSTEM_TICKS + delay; + add_timer(&wan_timer->timer_info); +#elif defined(__FreeBSD__) + wan_timer->timer_info = + timeout(wan_timer->timer_func, + (void*)wan_timer->timer_arg, + delay); + WAN_ASSERT1(wan_timer->timer_info.callout == NULL); +#elif defined(__OpenBSD__) + timeout_add(&wan_timer->timer_info, delay); +#elif defined(__NetBSD__) + wan_timer->timer_info.c_time = delay; + callout_reset(&wan_timer->timer_info, + delay, + wan_timer->timer_func, + wan_timer->timer_arg); +#else +# error "wan_add_timer() function is not supported yet!" +#endif /* linux */ + return 0; +} + +/********************** WANPIPE KERNEL BUFFER **************************/ +/* +** wan_skb_data() - +** Returns pointer to data. +*/ +static __inline unsigned char* wan_skb_data(void* skb) +{ +#if defined(__LINUX__) + return ((struct sk_buff*)skb)->data; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + return mtod((struct mbuf*)skb, caddr_t); +#elif defined(__SOLARIS__) + return ((netskb_t*)mp)->b_rptr; +#else +# error "wan_skb_data() function is not supported yet!" +#endif +} + +/* +** wan_skb_tail() - +** Returns pointer to data. +*/ +static __inline unsigned char* wan_skb_tail(void* skb) +{ +#if defined(__LINUX__) + return wan_skb_tail_pointer((struct sk_buff*)skb); +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + return mtod((struct mbuf*)skb, caddr_t) + ((struct mbuf*)skb)->m_len; +#elif defined(__SOLARIS__) + return ((netskb_t*)mp)->b_wptr; +#else +# error "wan_skb_tail() function is not supported yet!" +#endif +} + +/* +** wan_skb_append() - +** Returns pointer to data. +*/ +static __inline void wan_skb_append(void* skbprev, void *skb, void *list) +{ +#if defined(__LINUX__) +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) + skb_append(skbprev,skb); +# else + skb_append(skbprev,skb,list); +# endif +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + m_cat (skbprev, skb); +#else +# error "wan_skb_append() function is not supported yet!" +#endif +} + + + +/* +** wan_skb_len() - +** Returns current kernel buffer length. +*/ +static __inline int wan_skb_len(void* skb) +{ +#if defined(__LINUX__) + return ((struct sk_buff*)skb)->len; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + return ((struct mbuf*)skb)->m_len; +#elif defined(__SOLARIS__) + mblk_t* tmp = skb; + int len = 0; + while(tmp) { + len += (tmp->b_wptr - tmp->b_rptr); + tmp = tmp->b_cont; + } + return len; +#else +# error "wan_skb_len() function is not supported yet!" +#endif +} + +/* +** wan_skb_free() - +** Free kernel memory buffer. +*/ +static __inline void wan_skb_free(void* skb) +{ +#if defined(__LINUX__) +#if defined(WAN_DEBUG_MEM) + DEBUG_SUB_MEM(((struct sk_buff*)skb)->truesize); +#endif + dev_kfree_skb_any(skb); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + m_freem(skb); +#elif defined(__SOLARIS__) + freemsg(skb); +#else +# error "wan_skb_free() function is not supported yet!" +#endif +} + +/* +** wan_skb_set_mark() - +** Set mark for skb. +*/ +static __inline void wan_skb_set_mark(void* pskb) +{ +#if defined(__LINUX__) + return; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + ((netskb_t*)pskb)->m_flags |= WAN_MFLAG_PRV; +#endif + return; +} + +/* +** wan_skb_clear_mark() - +** Clear mark from skb. +*/ +static __inline void wan_skb_clear_mark(void* pskb) +{ +#if defined(__LINUX__) + return; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + ((netskb_t*)pskb)->m_flags &= ~WAN_MFLAG_PRV; +#endif + return; +} + +/* +** wan_skb_mark() - +** Return 1 if mark is set, otherwise 0. +*/ +static __inline int wan_skb_mark(void* pskb) +{ +#if defined(__LINUX__) + return 0; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + return (((netskb_t*)pskb)->m_flags & WAN_MFLAG_PRV); +#endif + return 0; +} + +/* +** wan_skb_alloc() - +** Allocate kernel buffer with len. +*/ +static __inline void* wan_skb_alloc(unsigned int len) +{ +#if defined(__LINUX__) +#if defined(WAN_DEBUG_MEM) + struct sk_buff *skb=dev_alloc_skb(len); + if (skb){ + DEBUG_ADD_MEM(skb->truesize); + } + return (void*)skb; +#else + return (void*)dev_alloc_skb(len); +#endif +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf *new = NULL; + + if (len){ + MGETHDR(new, M_DONTWAIT, MT_DATA); + }else{ + MGET(new, M_DONTWAIT, MT_DATA); + } + if (new){ + if (new->m_flags & M_PKTHDR){ + new->m_pkthdr.len = 0; + } + new->m_len = 0; + MCLGET(new, M_DONTWAIT); + if ((new->m_flags & M_EXT) == 0){ + wan_skb_free(new); + return NULL; + } + /* Always reserve extra 16 bytes (as Linux) + ** for the header */ + new->m_data += 16; + wan_skb_set_mark(new); + return (void*)new; + } + return NULL; +#elif defined (__SOLARIS__) + mblk_t *mp=allocb(ROUNDUP(len+16, IOC_LINESIZE), BPRI_MED); + if (mp){ + caddr_t ptr= (caddr_t) ROUNDUP((long)mp->b_rptr, 1); + mp->b_rptr=(uchar_t *)ptr+16; + } + return mp; +#else +# error "wan_skb_alloc() function is not supported yet!" +#endif +} + +static __inline void* wan_skb_kalloc(unsigned int len) +{ +#if defined(__LINUX__) +#if defined(WAN_DEBUG_MEM) + struct sk_buff *skb=__dev_alloc_skb(len,GFP_KERNEL); + if (skb){ + DEBUG_ADD_MEM(skb->truesize); + } + return (void*)skb; +#else + return (void*)__dev_alloc_skb(len,GFP_KERNEL); +#endif +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf *new = NULL; + + if (len){ + MGETHDR(new, M_DONTWAIT, MT_DATA); + }else{ + MGET(new, M_DONTWAIT, MT_DATA); + } + if (new){ + if (new->m_flags & M_PKTHDR){ + new->m_pkthdr.len = 0; + } + new->m_len = 0; + MCLGET(new, M_DONTWAIT); + if ((new->m_flags & M_EXT) == 0){ + wan_skb_free(new); + return NULL; + } + /* Always reserve extra 16 bytes (as Linux) + ** for the header */ + new->m_data += 16; + wan_skb_set_mark(new); + return (void*)new; + } + return NULL; +#elif defined (__SOLARIS__) + mblk_t *mp=allocb(ROUNDUP(len+16, IOC_LINESIZE), BPRI_MED); + if (mp){ + caddr_t ptr= (caddr_t) ROUNDUP((long)mp->b_rptr, 1); + mp->b_rptr=(uchar_t *)ptr+16; + } + return mp; +#else +# error "wan_skb_kalloc() function is not supported yet!" +#endif +} + + +/* +** wan_skb_set_dev() - +** Set device point. +*/ +static __inline void wan_skb_set_dev(void* pskb, void* dev) +{ +#if defined(__LINUX__) + struct sk_buff *skb = (struct sk_buff*)pskb; + if (skb){ + skb->dev = dev; + } +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + netskb_t* m = (netskb_t*)pskb; + if (m){ + m->m_pkthdr.rcvif = dev; + } +#else +# error "wan_skb_set_dev() function is not supported yet!" +#endif +} + +static __inline void wan_skb_set_protocol(void* pskb, unsigned int protocol) +{ +#if defined(__LINUX__) + struct sk_buff *skb = (struct sk_buff*)pskb; + if (skb){ + skb->protocol = htons(protocol); + } +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf *mbuf = (struct mbuf*)pskb; + if (protocol == ETH_P_IPX){ + mbuf->m_flags |= M_PROTO1; + } +#else + +# warning "wan_skb_set_protocol() function is not supported yet!" +#endif +} + +static __inline void wan_skb_set_raw(void* pskb) +{ +#if defined(__LINUX__) + struct sk_buff *skb = (struct sk_buff*)pskb; + if (skb){ + wan_skb_reset_mac_header(skb); + wan_skb_reset_network_header(skb); + } +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#else +# warning "wan_skb_set_raw() function is not supported yet!" +#endif +} + + + +/* +** wan_skb_set_csum() - +** Set checksum. +*/ +static __inline void wan_skb_set_csum(void* skb, unsigned int csum) +{ +#if defined(__LINUX__) + struct sk_buff *sk = (struct sk_buff*)skb; + if (sk){ + sk->csum = csum; + } +#elif defined(__OpenBSD__) + netskb_t* m = (netskb_t*)skb; + if (m){ +# if (OpenBSD >= 200511) + m->m_pkthdr.csum_flags = csum; +# else + m->m_pkthdr.csum = csum; +# endif + } +#elif defined(__NetBSD__) || defined(__FreeBSD__) + netskb_t* m = (netskb_t*)skb; + if (m){ + m->m_pkthdr.csum_data = csum; + } +#else +# error "wan_skb_set_csum() function is not supported yet!" +#endif +} + +/* +** wan_skb_csum() - +** Return checksum value. +*/ +static __inline unsigned int wan_skb_csum(void* skb) +{ +#if defined(__LINUX__) + struct sk_buff *sk = (struct sk_buff*)skb; + return (sk) ? sk->csum : 0; +#elif defined(__NetBSD__) || defined(__FreeBSD__) + netskb_t* m = (netskb_t*)skb; + return (m) ? m->m_pkthdr.csum_data : 0; +#elif defined(__OpenBSD__) + netskb_t* m = (netskb_t*)skb; +# if (OpenBSD >= 200511) + return (m) ? m->m_pkthdr.csum_flags : 0; +# else + return (m) ? m->m_pkthdr.csum : 0; +# endif +#else +# error "wan_skb_set_dev() function is not supported yet!" +#endif +} + +/* +** wan_skb_check() - +** Check if packet consists from one skb block. +*/ +static __inline int wan_skb_check(void* skb) +{ +#if defined(__LINUX__) + return 0; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + netskb_t* m = (netskb_t*)skb; + if (m->m_pkthdr.len != m->m_len){ + return 1; + } + return 0; +#else +# error "wan_skb_check() function is not supported yet!" +#endif +} + +/* +** wan_skb_reserve() - +** Reserve extra bytes before data +*/ +static __inline void wan_skb_reserve(void* skb, unsigned int len) +{ +#if defined(__LINUX__) + skb_reserve(skb, len); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf *m = (struct mbuf*)skb; + + m->m_data += len; +#else +# error "wan_skb_free() function is not supported yet!" +#endif +} + +/* +** wan_skb_copyback() - +** Copy data from a buffer back into the indicated mbuf chain, +** starting "off" bytes from the beginning, extending the mbuf +** chain if necessary. +*/ +static __inline void wan_skb_copyback(void* skb, int off, int len, caddr_t cp) +{ +#if defined(__LINUX__) + struct sk_buff* sk = (struct sk_buff*)skb; + unsigned char* data = NULL; + if (off == wan_skb_len(skb)){ + if (len > wan_skb_tailroom(sk)){ + DEBUG_EVENT("wan_skb_copyback: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + off, len, wan_skb_len(skb)); + return; + }else{ + data = skb_put(skb, len); + memcpy(data, cp, len); + } + }else{ + if (off + len > wan_skb_len(skb)){ + data = skb_put(skb, len); + memcpy(data + off, cp, len); + skb_trim(skb, off + len); + } + } +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf* m = (struct mbuf*)skb; + caddr_t data = mtod(m, caddr_t); + + bcopy(cp, &data[off], len); + m->m_len = off + len; + m->m_pkthdr.len = off + len; +#else +# error "wan_skb_copyback() function is not supported yet!" +#endif +} + +/* +** wan_skb_copyback_user() - +** Copy data from a buffer back into the indicated mbuf chain, +** starting "off" bytes from the beginning, extending the mbuf +** chain if necessary. +** Data being copied is coming from user space, thus we must +** use a special function to copy it into kernel space. +*/ +static __inline int wan_skb_copyback_user(void* skb, int off, int len, caddr_t cp) +{ +#if defined(__LINUX__) + struct sk_buff* sk = (struct sk_buff*)skb; + unsigned char* data = NULL; + if (off == wan_skb_len(skb)){ + if (len > wan_skb_tailroom(sk)) { + DEBUG_EVENT("wan_skb_copyback_user: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + off, len, wan_skb_len(skb)); + return -EINVAL; + }else{ + data = skb_put(skb, len); + if (WAN_COPY_FROM_USER(data, cp, len)){ + DEBUG_EVENT("wan_skb_copyback_user: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + off, len, wan_skb_len(skb)); + return -EFAULT; + } + } + }else{ + if (off + len > wan_skb_len(skb)){ + data = skb_put(skb, len); + if (WAN_COPY_FROM_USER(data+off, cp, len)){ + DEBUG_EVENT("wan_skb_copyback_user: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + off, len, wan_skb_len(skb)); + return -EFAULT; + } + skb_trim(skb, off + len); + } + } + return 0; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf* m = (struct mbuf*)skb; + caddr_t data = mtod(m, caddr_t); + + WAN_COPY_FROM_USER(cp, &data[off], len); + m->m_len = off + len; + m->m_pkthdr.len = off + len; +#else +# error "wan_skb_copyback_user() function is not supported yet!" +#endif + return 0; +} + + +/* +** wan_skb_copyback() - +** Copy data from an mbuf chain starting "off" bytes from the beginning, +** continuing for "len" bytes, into the indicated buffer. +*/ +static __inline void wan_skb_copydata(void* skb, int off, int len, caddr_t cp) +{ +#if defined(__LINUX__) + if (off + len > wan_skb_len(skb)){ + DEBUG_EVENT("wan_skb_copydata: Internal error (off=%d, len=%d, skb_len=%d)!\n", + off, len, wan_skb_len(skb)); + return; + } + memcpy(cp, wan_skb_data(skb), len); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + caddr_t data = mtod((struct mbuf*)skb, caddr_t); + + bcopy(cp, &data[off], len); +#elif defined(__SOLARIS__) + mblk_t* tmp = (mblk_t*)skb; + unsigned char* ptr = NULL; + unsigned i = 0, num = 0; + while(tmp != NULL) { + ptr = tmp->b_rptr; + num = tmp->b_wptr - tmp->b_rptr; + bcopy(ptr, &cp[i], num); + i += num; + tmp = tmp->b_cont; + } +#else +# error "wan_skb_copydata() function is not supported yet!" +#endif +} + +/* +** wan_skb_copy() +*/ +static __inline void * wan_skb_copy(void *skb) +{ +#if defined(__LINUX__) + return skb_copy(skb,GFP_ATOMIC); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + return m_copym(skb, 0, wan_skb_len(skb), M_DONTWAIT); +#else +# error "wan_skb_copy() function is not supported yet" +#endif + +} + +/* +** wan_skb_clone() +*/ +static __inline void * wan_skb_clone(void *skb) +{ +#if defined(__LINUX__) + return skb_clone(skb,GFP_ATOMIC); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + return m_copym(skb, 0, wan_skb_len(skb), M_DONTWAIT); +#else +# error "wan_skb_clone() function is not supported yet" +#endif + +} + + + + + +/* +** wan_skb2buffer() - +** Correct skb block. +*/ +static __inline int wan_skb2buffer(void** skb) +{ +#if defined(__LINUX__) + return 0; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + netskb_t *m = (netskb_t*)(*skb); + netskb_t *new = NULL; + + new = wan_skb_alloc(0); + if (new){ + struct mbuf *tmp = m; + char *buffer = new->m_data; + + for( ; tmp; tmp = tmp->m_next) { + bcopy(mtod(tmp, caddr_t), buffer, tmp->m_len); + buffer += tmp->m_len; + new->m_len += tmp->m_len; + } + wan_skb_free(m); + *skb = new; + return 0; + } + return -EINVAL; +#else +# error "wan_skb_correct() function is not supported yet!" +#endif +} + +/* +** wan_skb_pull() - +** +*/ +static __inline unsigned char* wan_skb_pull(void* skb, int len) +{ +#if defined(__LINUX__) + return skb_pull((struct sk_buff*)skb, len); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + m_adj(skb, len); +#if 0 + struct mbuf* m = (struct mbuf*)skb; + m->m_data += len; + m->m_pkthdr.len -= len; + m->m_len = m->m_pkthdr.len; +#endif + return wan_skb_data(skb); +#else +# error "wan_skb_pull() function is not supported yet!" +#endif +} + +/* +** wan_skb_put() - +** +*/ +static __inline unsigned char* wan_skb_put(void* skb, int len) +{ +#if defined(__LINUX__) + return skb_put((struct sk_buff*)skb, len); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf* m = (struct mbuf*)skb; + int org_len = wan_skb_len(skb); + unsigned char* data = wan_skb_data(skb); + + m->m_len = org_len + len; + m->m_pkthdr.len = org_len + len; +/*Alex Sep27,2004 last tail but not data pointer return wan_skb_data(skb);*/ + return data + org_len; +#elif defined(__SOLARIS__) + mblk_t mp=(mblk_t*)skb; + unsigned char *wptr=mp->b_wptr; + mp->b_wptr += len; + return mp->b_wptr; +#else +# error "wan_skb_put() function is not supported yet!" +#endif +} + +/* +** wan_skb_push() - +** +*/ +static __inline unsigned char* wan_skb_push(void* skb, int len) +{ +#if defined(__LINUX__) + return skb_push((struct sk_buff*)skb, len); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf *m = (struct mbuf*)skb; + int org_len = wan_skb_len(skb); + + if (m->m_flags & M_EXT){ + if ((m->m_data - len) < m->m_ext.ext_buf){ + DEBUG_EVENT("Can't push %d bytes!\n", len); + return wan_skb_data(skb); + } + }else{ + if ((m->m_data - len) < m->m_pktdat){ + DEBUG_EVENT("Can't push %d bytes!\n", len); + return wan_skb_data(skb); + } + } + m->m_data -= len; + m->m_len = org_len + len; + m->m_pkthdr.len = org_len + len; + return wan_skb_data(skb); +#else +# error "wan_skb_push() function is not supported yet!" +#endif +} + + + + +/* +** wan_skb_tailroom() - Tail room +** +** +*/ +static __inline int wan_skb_tailroom(void* skb) +{ +#if defined(__LINUX__) + return skb_tailroom(skb); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf* m = (struct mbuf*)skb; + + if (m->m_flags & M_EXT){ + return (MCLBYTES - m->m_len); + } + return (MHLEN - m->m_len); +#else +# error "wan_skb_tailroom() function is not supported yet!" +#endif +} + +/* +** wan_skb_tailroom() - Head room +** +** +*/ +static __inline int wan_skb_headroom(void* skb) +{ +#if defined(__LINUX__) + return skb_headroom(skb); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf* m = (struct mbuf*)skb; + + if (m->m_flags & M_EXT){ + return (m->m_data - m->m_ext.ext_buf); + } + return (m->m_data - m->m_pktdat); +#else +# error "wan_skb_headroom() function is not supported yet!" +#endif +} + + + +/* +** wan_skb_trim() - Trim from tail +** +** +*/ +static __inline void wan_skb_trim(void* skb, unsigned int len) +{ +#if defined(__LINUX__) + skb_trim(skb, len); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf* m = (struct mbuf*)skb; +#if 0 + /* Trim only moves tail to head+len (Oct13) */ + if (len == 0){ + m->m_data = m->m_ext.ext_buf; + } +#endif + m->m_pkthdr.len = len; + m->m_len = m->m_pkthdr.len; +#else +# error "wan_skb_trim() function is not supported yet!" +#endif +} + +/* +** wan_skb_init() - Setup skb data ptr +** +** +*/ +static __inline void wan_skb_init(void* pskb, unsigned int len) +{ +#if defined(__LINUX__) + struct sk_buff* skb = (struct sk_buff*)pskb; + skb->data = skb->head + len; + wan_skb_reset_tail_pointer(skb); + skb->len = 0; + skb->data_len = 0; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf* m = (struct mbuf*)pskb; + m->m_data = m->m_ext.ext_buf + len; +#else +# error "wan_skb_init() function is not supported yet!" +#endif +} + +static __inline int wan_skb_print(void* skb) +{ +#if defined(__LINUX__) + int len = wan_skb_len(skb); + unsigned char *data = wan_skb_data(skb); + int i; + + DEBUG_EVENT("DBG Packet %d bytes: ",len); + for(i=0;im_pkthdr.len, i; + unsigned char *data = wan_skb_data(skb); + + if (m->m_type & M_PKTHDR) + DEBUG_EVENT("M_PKTHDR flag set (%d)!\n", + m->m_pkthdr.len); + if (m->m_type & M_EXT) + DEBUG_EVENT("M_EXT flag set (%d)!\n", + m->m_pkthdr.len); + DEBUG_EVENT("Packet %d bytes: ", len); + for(i=0;i= '0') && (ifname[len] <= '9')){ + if (!base){ + int i=0; + base = 1; + for(i=0;i= 502000) + if_initname(dev, ifname, IF_DUNIT_NONE); +# else + dev->if_unit = ifunit; + if (dev->if_name == NULL){ + dev->if_name = wan_malloc(prefix_len+1); + if (dev->if_name == NULL){ + return -ENOMEM; + } + } + memcpy(dev->if_name, ifname, prefix_len); + dev->if_name[prefix_len] = '\0'; +# endif + WAN_IFQ_SET_MAXLEN(&dev->if_snd, ifqmaxlen); +#elif defined(__OpenBSD__) || defined(__NetBSD__) + if (strlen(ifname) >= IFNAMSIZ){ + return -ENOMEM; + } + bcopy(ifname, dev->if_xname, strlen(ifname)); + WAN_IFQ_SET_MAXLEN(&dev->if_snd, IFQ_MAXLEN); +#elif defined(__LINUX__) +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) + dev->name = ifname; +# else + strcpy(dev->name, ifname); +# endif +#else +# error "wan_netif_init() function is not supported yet!" +#endif + return 0; +} + +static __inline int wan_netif_del(netdevice_t* dev) +{ + WAN_ASSERT(dev == NULL); +#if defined(__FreeBSD__) + dev->if_init = NULL; +# if (__FreeBSD_version >= 502000) + dev->if_dname = NULL; +# elif (__FreeBSD_version > 400000) + /* Free interface name (only for FreeBSD-4.0) */ + free(dev->if_name, M_DEVBUF); +# endif +#elif defined(__OpenBSD__) || defined(__NetBSD__) + /* Do nothing */ +#elif defined(__LINUX__) + /* Do nothing */ +#else +# error "wan_netif_del() function is not supported yet!" +#endif + return 0; +} + + +#if defined(__LINUX__) +static __inline void wan_netif_fake_init(netdevice_t *d) +{ + return; +} +#endif + +static __inline void* +wan_netif_alloc(unsigned char *devname, int ifType, int *err) +{ +#if defined(__LINUX__) +# if defined(LINUX_2_6) +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)) + return __dev_alloc(devname, err); +# else + return alloc_netdev(0,devname,wan_netif_fake_init); +# endif +# elif defined(LINUX_2_4) + netdevice_t *dev=wan_malloc(sizeof(netdevice_t)); + *err=0; + + if (!dev){ + *err=-ENOMEM; + } + memset(dev, 0, sizeof(netdevice_t)); + + strncpy(dev->name,devname,30); + return dev; +# else + netdevice_t *dev=wan_malloc(sizeof(netdevice_t)); + *err=0; + + if (!dev){ + *err=-ENOMEM; + } + memset(dev, 0, sizeof(netdevice_t)); + + dev->name=wan_malloc(35); + if (!dev->name){ + wan_free(dev); + dev=NULL; + *err=-ENOMEM; + return NULL; + } + strncpy(dev->name,devname,30); + return dev; +# endif +#elif defined(__FreeBSD__) && (__FreeBSD_version > 600000) + struct ifnet* ifp; + ifp = IFALLOC(ifType); + /*ifp = wan_malloc(sizeof(struct ifnet));*/ + if (ifp == NULL){ + *err = -ENOMEM; + return NULL; + } + if (devname){ + *err = wan_netif_init(ifp, devname); + if (*err){ + wan_netif_del(ifp); + return NULL; + } + } + return ifp; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct ifnet* ifp; + switch(ifType){ + case WAN_IFT_PPP: + ifp = (struct ifnet*)wan_malloc(sizeof(struct sppp)); + if (ifp) bzero((struct sppp*)ifp, sizeof(struct sppp)); + break; + case WAN_IFT_ETHER: + ifp = (struct ifnet*)wan_malloc(sizeof(wan_ethercom_t)); + if (ifp) bzero(WAN_IFP2AC(ifp), sizeof(wan_ethercom_t)); + break; + case WAN_IFT_OTHER: + default: + ifp = wan_malloc(sizeof(struct ifnet)); + if (ifp) bzero(ifp, sizeof(struct ifnet)); + break; + } + /*ifp = IFALLOC(ifType);*/ + /*ifp = wan_malloc(sizeof(struct ifnet));*/ + if (ifp == NULL){ + *err = -ENOMEM; + return NULL; + } + if (devname){ + *err = wan_netif_init(ifp, devname); + if (*err){ + wan_netif_del(ifp); + return NULL; + } + } + return ifp; +#else +# error "wan_netif_alloc() unsupported" +#endif + +} + +static __inline void wan_netif_free(netdevice_t *dev) +{ + +#if defined(__LINUX__) +# if defined(LINUX_2_6) + free_netdev(dev); +# elif defined(LINUX_2_4) + wan_free(dev); +# else + if (dev->name){ + wan_free(dev->name); + dev->name=NULL; + } + wan_free(dev); +# endif +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + wan_netif_del(dev); + IFFREE(dev); /*wan_free(dev);*/ +#else +#error "wan_netif_free() not supported!" +#endif + +} + + +static __inline char* wan_netif_name(netdevice_t* dev) +{ + static char ifname[IFNAMSIZ+1]; + WAN_ASSERT2(dev == NULL, NULL); +#if defined(__LINUX__) + strcpy(ifname, dev->name); +#elif defined(__FreeBSD__) +# if (__FreeBSD_version >= 502000) + strcpy(ifname, dev->if_xname); +# else + sprintf(ifname, "%s%d", dev->if_name, dev->if_unit); +# endif +#elif defined(__OpenBSD__) || defined(__NetBSD__) + sprintf(ifname, "%s", dev->if_xname); +#else +# error "wan_get_ifname() function is not supported yet!" +#endif + return ifname; +} + +static __inline void* wan_netif_priv(netdevice_t* dev) +{ + WAN_ASSERT2(dev == NULL, NULL); +#if defined(__LINUX__) + return dev->priv; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + return dev->if_softc; +#else +# error "wan_netif_priv() function is not supported yet!" +#endif +} + +static __inline int wan_netif_up(netdevice_t* dev) +{ + WAN_ASSERT2(dev == NULL, -EINVAL); +#if defined(__LINUX__) + return WAN_NETIF_UP(dev); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + return WAN_NETIF_UP(dev); +#else +# error "wan_netif_up() function is not supported yet!" +#endif +} + + +static __inline void wan_netif_set_priv(netdevice_t* dev, void* priv) +{ + WAN_ASSERT1(dev == NULL); +#if defined(__LINUX__) + dev->priv = priv; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + dev->if_softc = priv; +#else +# error "wan_netif_priv() function is not supported yet!" +#endif + return; +} + +static __inline short wan_netif_flags(netdevice_t* dev) +{ + WAN_ASSERT(dev == NULL); +#if defined(__LINUX__) + return dev->flags; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + return dev->if_flags; +#else +# error "wan_netif_flags() function is not supported yet!" +#endif +} + +static __inline int wan_netif_mcount(netdevice_t* dev) +{ +#if defined(__LINUX__) + return dev->mc_count; +#elif defined(__FreeBSD__) + return dev->if_amcount; +#elif defined(__OpenBSD__) || defined(__NetBSD__) + return 0; +#else +# error "wan_netif_mcount() function is not supported yet!" +#endif +} + +static __inline int wan_netif_set_ticks(netdevice_t* dev, unsigned long ticks) +{ +#if defined(__LINUX__) + dev->trans_start = ticks; +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#else +# error "wan_netif_set_ticks() function is not supported yet!" +#endif + return 0; +} + +static __inline int wan_netif_set_mtu(netdevice_t* dev, unsigned long mtu) +{ +#if defined(__LINUX__) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + dev->if_mtu = mtu; +#else +# error "wan_netif_set_mtu() function is not supported yet!" +#endif + return 0; +} + + +static __inline void +wan_bpf_report(netdevice_t* dev, void* pkt, int flag, int dir) +{ + +#if defined(__LINUX__) + /* Do nothing */ +#elif defined(__FreeBSD__) + if (dev->if_bpf != NULL){ /* BF-0002 */ + WAN_BPF_REPORT(dev, pkt); + } +#elif defined(__OpenBSD__) || defined(__NetBSD__) + if (dev->if_bpf != NULL){ /* BF-0002 */ + if (flag){ + struct mbuf m0; + u_int32_t af = AF_INET; + m0.m_next = pkt; + m0.m_len = 4; + m0.m_data = (char*)⁡ + WAN_BPF_REPORT(dev, &m0, dir); + }else{ + WAN_BPF_REPORT(dev, pkt, dir); + } + } +#else +# error "wan_bpf_report() function is not supported yet!" +#endif +} + + + + + +static __inline void wan_spin_lock_init(void *lock) +{ +#if defined(__LINUX__) + spin_lock_init(((spinlock_t*)lock)); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + /*(*(wan_smp_flag_t*)flag) = 0;*/ +#else +# warning "wan_spin_lock_init() function is not supported yet!" +#endif +} + +static __inline int wan_spin_is_locked(void *lock) +{ +#if defined(__LINUX__) + return spin_is_locked((spinlock_t*)lock); +#elif defined(__NetBSD__) || defined(__OpenBSD__) + return 0;/*((*(wan_smp_flag_t*)flag) & imask[IPL_NET]);*/ +#elif defined(__FreeBSD__) +# if (__FreeBSD_version > 500000) + return 0; +# else + return 0;/*((*(wan_smp_flag_t*)flag) & net_imask);*/ +# endif +#else +# warning "wan_spin_is_lock() function is not supported yet!" +#endif +} + +static __inline void wan_spin_lock_irq(void *lock, wan_smp_flag_t *flag) +{ +#if defined(__LINUX__) + spin_lock_irqsave(((spinlock_t*)lock),*flag); +#elif defined(__FreeBSD__) + /* Feb 10, 2005 Change splnet to splimp + ** (i think it was cause to system crash) */ + *flag = splimp(); +#elif defined(__OpenBSD__) + *flag = splnet(); +#elif defined(__NetBSD__) +# if (__NetBSD_Version__ >= 106000200) + *flag = splvm(); +# else + *flag = splimp(); +# endif +#else +# warning "wan_spin_lock_irq() function is not supported yet!" +#endif +} +static __inline void wan_spin_unlock_irq(void *lock, wan_smp_flag_t *flag) +{ +#if defined(__LINUX__) + spin_unlock_irqrestore(((spinlock_t*)lock),*flag); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + splx(*flag); +#else +# warning "wan_spin_unlock_irq() function is not supported yet!" +#endif +} + +static __inline void wan_spin_lock(void *lock) +{ +#if defined(__LINUX__) + spin_lock(((spinlock_t*)lock)); +#elif defined(__FreeBSD__) + /* Feb 10, 2005 Change splnet to splimp + ** (i think it was cause to system crash) */ + *((wan_spinlock_t*)lock) = splimp(); +#elif defined(__OpenBSD__) + *((wan_spinlock_t*)lock) = splnet(); +#elif defined(__NetBSD__) +# if (__NetBSD_Version__ >= 106000200) + *((wan_spinlock_t*)lock) = splvm(); +# else + *((wan_spinlock_t*)lock) = splimp(); +# endif +#else +# warning "wan_spin_lock() function is not supported yet!" +#endif +} +static __inline void wan_spin_unlock(void *lock) +{ +#if defined(__LINUX__) + spin_unlock(((spinlock_t*)lock)); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + splx(*(wan_spinlock_t*)lock); +#else +# warning "wan_spin_unlock() function is not supported yet!" +#endif +} + + + +#if 0 +static __inline void wan_read_rw_lock(void *lock) +{ +#if defined(__LINUX__) + read_lock(((rwlock_t*)lock)); +#else +# warning "wan_read_rw_lock() function is not supported yet!" +#endif +} + +static __inline void wan_read_rw_unlock(void *lock) +{ +#if defined(__LINUX__) + read_unlock(((rwlock_t*)lock)); +#else +# warning "wan_read_rw_unlock() function is not supported yet!" +#endif +} + +static __inline void wan_write_rw_lock_irq(void *lock, unsigned long *flag) +{ +#if defined(__LINUX__) + write_lock_irqsave(((rwlock_t*)lock),flag); +#else +# warning "wan_read_rw_lock() function is not supported yet!" +#endif +} + +static __inline void wan_write_rw_unlock_irq(void *lock, unsigned long *flag) +{ +#if defined(__LINUX__) + write_unlock_irqrestore(((rwlock_t*)lock),flag); +#else +# warning "wan_read_rw_unlock() function is not supported yet!" +#endif +} +#endif + +#if 0 +static __inline void wan_read_bus_4(void *phw, void *virt, int offset, unsigned int *value) +{ +#if defined(__LINUX__) + *value = wp_readl((unsigned char*)virt + offset); +#else + sdla_bus_read_4(phw,offset,value); +#endif +} + +static __inline void wan_write_bus_4(void *phw, void *virt, int offset, unsigned int value) +{ +#if defined(__LINUX__) + wp_writel(value,(u8*)virt + offset); +#else + sdla_bus_write_4(phw,offset,value); +#endif +} +#endif + +#endif /* WAN_KERNEL */ +#endif /* __WANPIPE_COMMON_H */ diff --git a/patches/kdrivers/include/wanpipe_debug.h b/patches/kdrivers/include/wanpipe_debug.h index 7fddc02..990f8dd 100644 --- a/patches/kdrivers/include/wanpipe_debug.h +++ b/patches/kdrivers/include/wanpipe_debug.h @@ -50,6 +50,7 @@ # define DEBUG_NONE if (0) DbgPrint # define PRINT OutputLogString # define DEBUG_PRINT DbgPrint +# define DEBUG_LIMIT DbgPrint # define _DEBUG_PRINT DbgPrint # define DEBUG_KERNEL DEBUG_NONE @@ -239,11 +240,14 @@ # if (defined __FreeBSD__) || (defined __OpenBSD__) || defined(__NetBSD__) # define DEBUG_PRINT(format,msg...) log(LOG_INFO, format, ##msg) +# define DEBUG_LIMIT(format,msg...) log(LOG_INFO, format, ##msg) # define _DEBUG_PRINT(format,msg...) log(LOG_INFO, format, ##msg) # else /* !__FreeBSD__ && !__OpenBSD__ */ # define DEBUG_PRINT(format,msg...) printk(KERN_INFO format, ##msg) +# define DEBUG_LIMIT(format,msg...) printk(KERN_INFO format, ##msg) +//# define DEBUG_LIMIT(format,msg...) if (WAN_NET_RATELIMIT()) printk(KERN_INFO format, ##msg) # define _DEBUG_PRINT(format,msg...) printk(format,##msg) # endif /* __FreeBSD__ || __OpenBSD__ */ diff --git a/patches/kdrivers/include/wanpipe_defines.h b/patches/kdrivers/include/wanpipe_defines.h index e631386..cc8cce4 100644 --- a/patches/kdrivers/include/wanpipe_defines.h +++ b/patches/kdrivers/include/wanpipe_defines.h @@ -659,6 +659,7 @@ typedef struct wan_udp_hdr{ # define WP_DELAY DELAY # define WP_SCHEDULE(arg,name) tsleep(&(arg),PPAUSE,(name),(arg)) # define SYSTEM_TICKS ticks +typedef int wan_ticks_t; # define HZ hz # define RW_LOCK_UNLOCKED 0 # define ETH_P_IP AF_INET @@ -675,6 +676,7 @@ typedef struct wan_udp_hdr{ # define WP_DELAY DELAY # define WP_SCHEDULE(arg,name) tsleep(&(arg),PPAUSE,(name),(arg)) # define SYSTEM_TICKS ticks +typedef int wan_ticks_t; # define HZ hz # define RW_LOCK_UNLOCKED 0 # define ETH_P_IP AF_INET @@ -690,6 +692,7 @@ typedef struct wan_udp_hdr{ # define WAN_MOD_UNLOAD LKM_E_UNLOAD # define WP_DELAY DELAY # define SYSTEM_TICKS tick +typedef int wan_ticks_t; # define HZ hz # define RW_LOCK_UNLOCKED 0 # define WAN_IFT_OTHER IFT_OTHER @@ -701,6 +704,7 @@ typedef struct wan_udp_hdr{ # define WP_DELAY(usecs) udelay(usecs) # define atomic_set_int(name, val) atomic_set(name, val) # define SYSTEM_TICKS jiffies +typedef unsigned long wan_ticks_t; # define WP_SCHEDULE(arg,name) schedule() # define wan_atomic_read atomic_read # define wan_atomic_set atomic_set diff --git a/patches/kdrivers/include/wanpipe_lip.h b/patches/kdrivers/include/wanpipe_lip.h index 969df1f..9eeca02 100644 --- a/patches/kdrivers/include/wanpipe_lip.h +++ b/patches/kdrivers/include/wanpipe_lip.h @@ -166,7 +166,7 @@ enum { /*#define MAX_TX_BUF 10*/ #define MAX_TX_BUF 10 #define MAX_ATM_TX_BUF 35 -#define MAX_RX_Q 32 +#define MAX_RX_Q 128 #define WPLIP_MAGIC_LINK 0xDAFE1234 #define WPLIP_MAGIC_DEV 0xDAFE4321 diff --git a/patches/kdrivers/include/wanpipe_lip.h~ b/patches/kdrivers/include/wanpipe_lip.h~ new file mode 100644 index 0000000..3d91b0b --- /dev/null +++ b/patches/kdrivers/include/wanpipe_lip.h~ @@ -0,0 +1,684 @@ +/* $Header: /usr/local/cvsroot/wanpipe_common/include/wanpipe_lip.h,v 1.38 2007/02/21 18:46:09 sangoma Exp $ */ + +#ifndef _WANPIPE_LIP_HEADER_ +#define _WANPIPE_LIP_HEADER_ + + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# if defined(CONFIG_PRODUCT_WANPIPE_LAPB) || defined(CONFIG_PRODUCT_WANPIPE_LIP_LAPD) +# include +# endif +# if defined(CONFIG_PRODUCT_WANPIPE_XDLC) +# include +# endif +#else +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# if defined(CONFIG_PRODUCT_WANPIPE_LAPB) || defined(CONFIG_PRODUCT_WANPIPE_LIP_LAPD) +# include +# endif +# if defined(CONFIG_PRODUCT_WANPIPE_LIP_KATM) +# include +# endif +# if defined(CONFIG_PRODUCT_WANPIPE_XDLC) +# include +# endif +# if defined(CONFIG_PRODUCT_WANPIPE_XMTP2) +# include +# endif +# include +# include + +# ifdef WPLIP_TTY_SUPPORT +# include +# include +# include +# endif + +#endif + + + + +#ifdef WAN_KERNEL + +/* + *********************************************************************************** + * * + * X25HDR.C is the 'C' header file for the Sangoma X.25 code for the S508 adapter. * + * * + *********************************************************************************** +*/ + +#define LIP_OK 0 +#define TCPIP 0 + +#define MAX_CALL_REQ_ASYNC_PKT 512 + +#define NON_D_OPT 3 +#define D_OPT 2 + +#define FLOW_CONTROL_MASK 0x1F + +#define ONE_BYTE 1 +#define MAX_TOKENS 31 + +#define MODNAME "wanpipe_lip" + +#define MAX_LINK_RX_Q_LEN 10 +#define MAX_TAIL_ROOM 16 +#define MAX_LIP_LINKS 255 + +#if 0 +/* This option defaults the inital network + * interface state to STOPPED/DISABLED. + * + * In this case, all traffic will be blocked + * and data pushed back up the protocol stack. + * This can cause memory starvation if there are + * many interfaces running, because each interface + * queue can be up to 100 packets, and fames will + * only be dropped once the queue is overfilled + * + * By disabling this option, all packets received + * by the interface in disconnected state, will be + * silently discarded with carrier stat incremented. + */ +#define WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF +#endif + +/* BH flags */ +enum{ + WPLIP_BH_RUNNING, + WPLIP_RX_FSM_RUNNING, + WPLIP_SMP_CONFLICT, + WPLIP_BH_AWAITING_KICK, + WPLIP_LINK_TIMER_EXPIRED, + WPLIP_MORE_LINK_TX, + WPLIP_LINK_DOWN, + WPLIP_KICK, + WPLIP_TTY_BUSY + +}; + + +/* LIP DEV Critical */ +enum { + WPLIP_TX_WINDOW_CLOSED, + WPLIP_SEND_AWAITING_KICK, + WPLIP_TIMER_EXPIRED, + WPLIP_DEV_DOWN, + WPLIP_DEV_UNREGISTER, + WPLIP_RX, + WPLIP_IOCTL_SMP, + WPLIP_DEV_SENDING +}; + +#define MAX_RX_FACIL_CODE 30 + +#define BH_DEBUG 0 + +#define SOFT_INIT 0 +#define HARD_INIT 1 +#define MAX_SOFTIRQ_TIMEOUT 2 + +/* + * Physical X25 Link + * Each Link can support multiple logical + * channels (svc). + */ +#define MAX_LCN 255 +#define MAX_DECODE_BUF_SZ 1000 +#define MAX_PROC_NAME 10 + +#ifndef MAX_PROC_EVENTS +#define MAX_PROC_EVENTS 20 +#endif +#define MAX_PROC_EVENT_SIZE X25_CALL_STR_SZ+200+1 + + +/*#define MAX_TX_BUF 10*/ +#define MAX_TX_BUF 32 +#define MAX_ATM_TX_BUF 35 +#define MAX_RX_Q 128 + +#define WPLIP_MAGIC_LINK 0xDAFE1234 +#define WPLIP_MAGIC_DEV 0xDAFE4321 +#define WPLIP_MAGIC_DEV_EL 0xDAFE4444 + +#define WPLIP_ASSERT_MAGIC(ptr,magic,ret) \ + if ((*(unsigned long*)ptr) != magic) { \ + DEBUG_EVENT("%s:%d: Error Invalid Magic number in Link dev!\n", \ + __FUNCTION__,__LINE__); \ + return ret ; \ + } +#define WPLIP_ASSERT_MAGIC_VOID(ptr,magic) \ + if ((*(unsigned long*)ptr) != magic) { \ + DEBUG_EVENT("%s:%d: Error Invalid Magic number in Link dev!\n", \ + __FUNCTION__,__LINE__); \ + return; \ + } + +struct wplip_dev; + +WAN_LIST_HEAD(wplip_link_list,wplip_link); + +typedef struct wplip_link +{ + unsigned long magic; + WAN_LIST_ENTRY(wplip_link) list_entry; + + /* List of all Logic channel + * devices attached to the link + * + * Packet direction UP + * */ + WAN_LIST_HEAD(,wplip_dev) list_head_ifdev; + unsigned int dev_cnt; + wan_rwlock_t dev_list_lock; + + + /* List of Tx Devices attached + * to the Link. + * + * Packet direction DOWN + * + * Eg. Load balancing over multiple + * links */ + + WAN_LIST_HEAD(,wplip_dev_list) list_head_tx_ifdev; + unsigned int tx_dev_cnt; + wan_rwlock_t tx_dev_list_lock; + + + unsigned char state; + unsigned char carrier_state; + unsigned char prot_state; + + void *prot; + wan_timer_t prot_timer; + + unsigned char protocol; + + + /* Internal control information */ + wan_timer_info_t timer; + + unsigned long tq_working; + + wan_rwlock_t map_lock; + void *api_sk_id; + + wan_spinlock_t bh_lock; + + unsigned char name [MAX_PROC_NAME]; +#if 0 + struct proc_dir_entry *proc_dir; + unsigned char *proc_event_log [MAX_PROC_EVENTS]; + atomic_t proc_event_offset; +#endif + + wan_skb_queue_t tx_queue; + wan_skb_queue_t rx_queue; + wan_tasklet_t task; + + struct wplip_dev *cur_tx; + + int link_num; + + atomic_t refcnt; + + unsigned char tty_opt; + +#ifdef WPLIP_TTY_SUPPORT + struct tty_struct *tty; + unsigned int tty_minor; + unsigned int tty_open; + unsigned char *tty_buf; + wan_skb_queue_t tty_rx; + wan_taskq_t tty_task_queue; + unsigned char async_mode; +#endif + + wan_taskq_t prot_task; + u32 latency_qlen; + +} wplip_link_t; + + +#define CALL_REQUEST_INFO_SZ 512 + + +/* + * The logic channel per link connection control structure. + */ +typedef struct wplip_dev{ + + wanpipe_common_t common; + + unsigned long magic; + WAN_LIST_ENTRY(wplip_dev) list_entry; + + unsigned short critical; + + /* Internal control information */ + wan_skb_queue_t tx_queue; + + /* The link we are part of */ + wplip_link_t *lip_link; + + void *sk_id; + unsigned char api_state; +#if defined(__LINUX__) + struct proc_dir_entry *dent; +#endif + struct net_device_stats ifstats; + + unsigned char used; + unsigned char protocol; + + unsigned char name[MAX_PROC_NAME]; + + unsigned char udp_pkt_data[sizeof(wan_udp_pkt_t)+10]; + unsigned int udp_pkt_len; + + unsigned long ipx_net_num; + + unsigned int prot_addr; + + unsigned int max_mtu_sz; + unsigned int max_mtu_sz_orig; + + atomic_t refcnt; + pid_t pid; + + unsigned int interface_down; + wan_taskq_t if_task; + +} wplip_dev_t; + +typedef struct wplip_dev_list +{ + unsigned long magic; + netdevice_t *dev; + WAN_LIST_ENTRY(wplip_dev_list) list_entry; +}wplip_dev_list_t; + + +typedef struct wplip_prot_iface +{ + unsigned int init; + wplip_prot_reg_t reg; + void*(*prot_link_register)(void *link_ptr, + char *devname, + void *cfg, + wplip_prot_reg_t *reg); + + int (*prot_link_unregister)(void *prot_ptr); + + void*(*prot_chan_register)(void *if_ptr, + void *prot_ptr, + char *devname, + void *cfg, + unsigned char type); + + int (*prot_chan_unregister)(void *chan_ptr); + + int (*open_chan) (void *chan_ptr); + int (*close_chan)(void *chan_ptr); + + int (*tx) (void *chan_ptr, void *skb, int type); + int (*ioctl) (void *chan_ptr, int cmd, void *arg); + int (*pipemon)(void *chan, + int cmd, + int dlci, + unsigned char* data, + unsigned int *len); + + int (*rx) (void *prot_ptr, void *rx_pkt); + int (*timer) (void *prot_ptr, unsigned int *period, unsigned int); + int (*bh) (void *); + int (*snmp) (void *, void *); + int (*task) (void *prot_ptr); + +}wplip_prot_iface_t; + +#define MAX_LIP_PROTOCOLS 255 + +#define WPLIP_PROT_ASSERT(prot,ret) \ + if (prot >= MAX_LIP_PROTOCOLS){ \ + DEBUG_EVENT("%s:%d: Lip Error: Invalid Protocol 0x%X\n",\ + __FUNCTION__,__LINE__,prot);\ + return ret; \ + } + +#define WPLIP_PROT_FUNC_ASSERT(prot,func,ret) \ + if (prot->func == NULL){ \ + DEBUG_EVENT("%s:%d: Lip Error: Protocol function not supported\n",\ + __FUNCTION__,__LINE__);\ + return ret; \ + } + +#define WPLIP_PROT_EXIST(prot,ret) \ + if (wplip_prot_ops[prot] == NULL){ \ + DEBUG_EVENT("%s:%d: Lip Error: Unsupported/UnCompiled Protocol 0x%X\n",\ + __FUNCTION__,__LINE__,prot);\ + return ret; \ + } + + +#define wplip_hold(_dev) wan_atomic_inc(&(_dev)->refcnt) +#define wplip_put(_dev) wan_atomic_dec(&(_dev)->refcnt) + +#define wplip_get_link(_reg) (_reg)->wplip_link +#define wplip_get_lipdev(_dev) (wplip_dev_t*)wan_netif_priv((_dev)) + +#define wplip_liplink_magic(_link) ((_link)->magic == WPLIP_MAGIC_LINK) +#define wplip_lipdev_magic(_lipdev) ((_lipdev)->magic == WPLIP_MAGIC_DEV) + + +/* Function Prototypes */ + +/* wanpipe_lip_iface.c */ +extern unsigned char wplip_link_num[]; +extern wan_rwlock_t wplip_link_lock; +extern struct wplip_link_list list_head_link; +extern int wplip_data_rx_up(wplip_dev_t* lip_dev, void *skb); +extern int wplip_data_tx_down(wplip_link_t *lip_link, void *skb); +extern int wplip_callback_tx_down(void *lip_dev, void *skb); +extern int wplip_link_callback_tx_down(void *lip_link, void *skb); +extern int wplip_callback_kick_prot_task(void *lip_link); +extern int wplip_set_hw_idle_frame (void *liplink_ptr, unsigned char *data, int len); + +/* wanpipe_lip_sub.c */ +extern wplip_link_t* wplip_create_link(char *devname); +extern void wplip_remove_link(wplip_link_t *lip_link); +extern void wplip_insert_link(wplip_link_t *lip_link); +extern int wplip_link_exists(wplip_link_t *lip_link); +extern void wplip_free_link(wplip_link_t *lip_link); +extern int wplip_lipdev_latency_change(wplip_link_t *lip_link); + + +#if 1 +extern wplip_dev_t* wplip_create_lipdev(char *dev_name,int); +#else +extern wplip_dev_t* wplip_create_lipdev(char *dev_name); +#endif +extern void wplip_free_lipdev(wplip_dev_t *lip_dev); +extern int wplip_lipdev_exists(wplip_link_t *lip_link, char *dev_name); +extern void wplip_remove_lipdev(wplip_link_t *lip_link, + wplip_dev_t *lip_dev); +extern void wplip_insert_lipdev(wplip_link_t *wplip_link, + wplip_dev_t *wplip_dev); + +extern unsigned int dec_to_uint (unsigned char* str, int len); + +/* wanpipe_lip_netdev.c */ +extern int wplip_open_dev(netdevice_t *dev); +extern int wplip_stop_dev(netdevice_t *dev); +extern struct net_device_stats * wplip_ifstats (netdevice_t *dev); +extern int wplip_if_send (netskb_t *skb, netdevice_t *dev); +extern int wplip_if_init(netdevice_t *dev); +extern void wplip_kick(void *wplip_id,int reason); + + +# ifdef WPLIP_TTY_SUPPORT +/* wanpipe_lip_tty.c */ +extern int wplip_reg_tty(wplip_link_t *lip_link, wanif_conf_t *conf); +extern int wplip_unreg_tty(wplip_link_t *lip_link); +extern int wanpipe_tty_trigger_poll(wplip_link_t *lip_link); +extern void wplip_tty_receive(wplip_link_t *lip_link, void *skb); +#endif + +/* wanpipe_lip_prot.c */ +extern int wplip_init_prot(void); +extern int wplip_free_prot(void); +extern int wplip_reg_link_prot(wplip_link_t *lip_link, wanif_conf_t *conf); +extern int wplip_unreg_link_prot(wplip_link_t *lip_link); +extern int wplip_reg_lipdev_prot(wplip_dev_t *lip_dev, wanif_conf_t *conf); +extern int wplip_unreg_lipdev_prot(wplip_dev_t *lip_dev); +extern int wplip_open_lipdev_prot(wplip_dev_t *lip_dev); +extern int wplip_close_lipdev_prot(wplip_dev_t *lip_dev); +extern int wplip_prot_rx(wplip_link_t *lip_link, netskb_t *skb); + +#if 0 +extern void wplip_prot_rx_kick(wplip_dev_t *lip_dev); +#endif +extern int wplip_prot_kick(wplip_link_t *lip_link, wplip_dev_t *lip_dev); +extern int wplip_prot_tx(wplip_dev_t *lip_dev, wan_api_tx_hdr_t *api_tx_hdr, netskb_t *skb, int type); +extern int wplip_prot_oob(wplip_dev_t *lip_dev, unsigned char*, int reason); +extern int wplip_prot_ioctl(wplip_dev_t *lip_dev, int cmd, void *arg); +extern int wplip_prot_udp_mgmt_pkt(wplip_dev_t * lip_dev, wan_udp_pkt_t *wan_udp_pkt); +extern int wplip_prot_udp_snmp_pkt(wplip_dev_t * lip_dev, int cmd, struct ifreq* ifr); + + +extern int wplip_link_prot_change_state(void *wplip_id, + int state, + unsigned char*,int); +extern int wplip_lipdev_prot_change_state(void *wplip_id, + int state, + unsigned char*,int); + + +extern unsigned int wplip_get_ipv4_addr (void *wplip_id, int type); +extern int wplip_set_ipv4_addr (void *wplip_id, + unsigned int, + unsigned int, + unsigned int, + unsigned int); +extern void wplip_add_gateway(void *wplip_id); +extern void wplip_trigger_if_task(wplip_dev_t *lip_dev); + +void wplip_ipxwan_switch_net_num(unsigned char *sendpacket, + unsigned long network_number, + unsigned long *orig_dnet, + unsigned long *orig_snet, + unsigned char incoming); + + +void wplip_ipxwan_restore_net_num(unsigned char *sendpacke, + unsigned long orig_dnet, + unsigned long orig_snet); + + +int wplip_handle_ipxwan(wplip_dev_t *lip_dev, void *skb); + +#if 0 +extern int gdbg_flag; +#endif + +static __inline int wplip_trigger_bh(wplip_link_t *lip_link) +{ + if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)){ + return -ENETDOWN; + } + + if (wan_skb_queue_len(&lip_link->rx_queue)){ + WAN_TASKLET_SCHEDULE((&lip_link->task)); + return 0; + } + + if (wan_test_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working)){ +#if 0 + if (gdbg_flag){ + DEBUG_EVENT("%s: Waiting for kick!\n", + __FUNCTION__); + } +#endif + return -EBUSY; + } + +#if 0 + gdbg_flag=0; +#endif + WAN_TASKLET_SCHEDULE((&lip_link->task)); + return 0; +} + +static __inline int wplip_kick_trigger_bh(wplip_link_t *lip_link) +{ + wan_clear_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); + WAN_TASKLET_SCHEDULE((&lip_link->task)); + return 0; +} + +static __inline int wplip_decode_protocol(wplip_dev_t *lip_dev, void *ptr) +{ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct sockaddr *sa = (struct sockaddr *)ptr; + + + switch (sa->sa_family){ + + case AF_INET: + return WPLIP_IP; + case AF_INET6: + return WPLIP_IPV6; + case AF_IPX: + return WPLIP_IPX; + default: + return WPLIP_IP; + } + +#elif defined(__LINUX__) + struct sk_buff *skb=(struct sk_buff*)ptr; + + if (lip_dev->common.usedby == BRIDGE || + lip_dev->common.usedby == BRIDGE_NODE){ + return WPLIP_ETH; + + } + + if (lip_dev->common.lip_prot == WANCONFIG_LAPD) { + return WPLIP_LAPD; + } + + if (lip_dev->common.usedby == STACK){ + switch (lip_dev->common.lip_prot){ + case WANCONFIG_PPP: + case WANCONFIG_TTY: + return WPLIP_PPP; + case WANCONFIG_FR: + return WPLIP_FR; + } + /* Break out down */ + } + + switch (htons(skb->protocol)){ + + case ETH_P_IP: + return WPLIP_IP; + case ETH_P_IPV6: + return WPLIP_IPV6; + case ETH_P_IPX: + return WPLIP_IPX; + } + + return WPLIP_IP; +#else +# error ("wplip_decode_protocol: Unknown Protocol!\n"); +#endif + +} + + +#if defined(__LINUX__) +static __inline void wp_lip_config_bridge_mode(wplip_dev_t *lip_dev) +{ + netdevice_t * dev = lip_dev->common.dev; + /* Setup the interface for Bridging */ + int hw_addr=0; + ether_setup(dev); + + /* Use a random number to generate the MAC address */ + memcpy(dev->dev_addr, "\xFE\xFC\x00\x00\x00\x00", 6); + get_random_bytes(&hw_addr, sizeof(hw_addr)); + *(int *)(dev->dev_addr + 2) += hw_addr; +} +#endif + + + +/*__KERNEL__*/ +#endif + +/*_WANPIPE_X25_HEADER_*/ +#endif + + + +#define WPLIP_ASSERT(reg,ret) if (!(reg)) {\ + DEBUG_EVENT("%s:%d Assert Error!\n", \ + __FUNCTION__,__LINE__); \ + return ret; \ + } + +#define WPLIP_ASSERT_VOID(reg) if (!(reg)) {\ + DEBUG_EVENT("%s:%d Assert Error!\n", \ + __FUNCTION__,__LINE__); \ + return; \ + } + +#define FUNC_BEGIN() DEBUG_EVENT("%s:%d ---Begin---\n",__FUNCTION__,__LINE__); +#define FUNC_END() DEBUG_EVENT("%s:%d ---End---\n\n",__FUNCTION__,__LINE__); + + +#define X25_DEBUG_MEM + +#ifdef X25_DEBUG_MEM + + #define X25_SKB_DEC(x) atomic_sub(x,&x25_skb_alloc) + #define X25_SKB_INC(x) atomic_add(x,&x25_skb_alloc) + + #define ALLOC_SKB(skb,len) { skb = dev_alloc_skb(len); \ + if (skb != NULL){ X25_SKB_INC(skb->truesize);}else{ WAN_MEM_ASSERT("X25");} } + #define KFREE_SKB(skb) { X25_SKB_DEC(skb->truesize); dev_kfree_skb_any(skb); } + + + #define X25_MEM_DEC(x) atomic_sub(x,&x25_mem_alloc) + #define X25_MEM_INC(x) atomic_add(x,&x25_mem_alloc) + + #define KMALLOC(ptr,len,flag) { ptr=kmalloc(len, flag); \ + if (ptr != NULL){ X25_MEM_INC(len);} else {WAN_MEM_ASSERT("X25");}} + #define KFREE(ptr) {X25_MEM_DEC(sizeof(*ptr)); kfree(ptr);} + +#else + #define KMALLOC(ptr,len,flag) ptr=kmalloc(len, flag) + #define KFREE(ptr) kfree(ptr) + + #define ALLOC_SKB(new_skb,len, dsp) new_skb = dev_alloc_skb(len) + #define KFREE_SKB(skb) dev_kfree_skb_any(skb) + + #define X25_SKB_DEC(x) + #define X25_SKB_INC(x) + #define X25_MEM_DEC(x) + #define X25_MEM_INC(x) +#endif + +#define is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0) diff --git a/patches/kdrivers/include/wanpipe_version.h b/patches/kdrivers/include/wanpipe_version.h index baa2aca..34bac28 100644 --- a/patches/kdrivers/include/wanpipe_version.h +++ b/patches/kdrivers/include/wanpipe_version.h @@ -2,13 +2,13 @@ #define __WANPIPE_VERSION__ -#define WANPIPE_COPYRIGHT_DATES "(c) 1994-2007" +#define WANPIPE_COPYRIGHT_DATES "(c) 1994-2008" #define WANPIPE_COMPANY "Sangoma Technologies Inc" /********** LINUX **********/ -#define WANPIPE_VERSION "3.2.1" +#define WANPIPE_VERSION "3.2.2" #define WANPIPE_SUB_VERSION "0" -#define WANPIPE_VERSION_BETA 1 +#define WANPIPE_VERSION_BETA 0 #define WANPIPE_LITE_VERSION "1.1.1" /********** FreeBSD **********/ diff --git a/patches/kdrivers/include/wanrouter.h b/patches/kdrivers/include/wanrouter.h index c10ef1d..e21d0ad 100644 --- a/patches/kdrivers/include/wanrouter.h +++ b/patches/kdrivers/include/wanrouter.h @@ -402,6 +402,8 @@ typedef struct wan_device unsigned char (*read_ec)(void*, unsigned short); int (*hwec_reset)(void* card_id, int); int (*hwec_enable)(void* card_id, int, int); + + void (*critical_event) (void *, int); } wan_device_t; WAN_LIST_HEAD(wan_devlist_, wan_device); diff --git a/patches/kdrivers/src/lip/wanpipe_lip_bh.c b/patches/kdrivers/src/lip/wanpipe_lip_bh.c index c4e690a..f62b569 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_bh.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_bh.c @@ -123,7 +123,6 @@ static int wplip_bh_transmit(wplip_link_t *lip_link) if (WAN_NETIF_QUEUE_STOPPED(lip_dev->common.dev)){ if (lip_dev->common.usedby == API){ - DEBUG_TEST("%s: Api waking stack!\n",lip_dev->name); WAN_NETIF_START_QUEUE(lip_dev->common.dev); #if defined(__LINUX__) wan_wakeup_api(lip_dev); diff --git a/patches/kdrivers/src/lip/wanpipe_lip_bh.c~ b/patches/kdrivers/src/lip/wanpipe_lip_bh.c~ new file mode 100644 index 0000000..13ae288 --- /dev/null +++ b/patches/kdrivers/src/lip/wanpipe_lip_bh.c~ @@ -0,0 +1,237 @@ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# include +#else +#include +#endif + +#if defined(__LINUX__) +void wplip_link_bh(unsigned long data); +#else +void wplip_link_bh(void* data, int pending); +#endif + +static int wplip_bh_receive(wplip_link_t *lip_link) +{ + netskb_t *skb; + unsigned long timeout_cnt = 2000; + int err; + + while((skb=wan_skb_dequeue(&lip_link->rx_queue)) != NULL){ + + err=wplip_prot_rx(lip_link,skb); + if (err){ + wan_skb_free(skb); + } + + if (--timeout_cnt == 0){ + DEBUG_EVENT("%s: Link RxBH Time squeeze\n",lip_link->name); + break; + } + } + + return 0; +} + +static int wplip_bh_transmit(wplip_link_t *lip_link) +{ + netskb_t *skb; + wplip_dev_t *lip_dev=NULL; + int err=0; + unsigned int timeout_cnt=1000; + + if (wan_test_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working)){ + if (wan_test_bit(WPLIP_KICK,&lip_link->tq_working)){ + DEBUG_TEST("%s: KICK but await still set!\n", + lip_link->name); + }else{ + return 0; + } + } + + wan_clear_bit(WPLIP_KICK,&lip_link->tq_working); + wan_clear_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); + + wan_clear_bit(WPLIP_MORE_LINK_TX,&lip_link->tq_working); + + while((skb=wan_skb_dequeue(&lip_link->tx_queue))){ + err=wplip_data_tx_down(lip_link,skb); + if (err != 0){ + wan_skb_queue_head(&lip_link->tx_queue,skb); + wan_set_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); + goto wplip_bh_link_transmit_exit; + } + + if (--timeout_cnt == 0){ + DEBUG_EVENT("%s: Link TxBH Time squeeze\n",lip_link->name); + goto wplip_bh_link_transmit_exit; + } + } + + if ((lip_dev=lip_link->cur_tx) != NULL){ + + if (lip_dev->magic != WPLIP_MAGIC_DEV){ + DEBUG_EVENT("%s: Error1: Invalid Dev Magic dev=%p Magic=0x%lX\n", + lip_link->name, + lip_dev, + lip_dev->magic); + goto wplip_bh_transmit_exit; + } + + }else{ + lip_dev=WAN_LIST_FIRST(&lip_link->list_head_ifdev); + if (!lip_dev){ + goto wplip_bh_transmit_exit; + } + + if (lip_dev->magic != WPLIP_MAGIC_DEV){ + DEBUG_EVENT("%s: Error2: Invalid Dev Magic dev=%p Magic=0x%lX\n", + lip_link->name, + lip_dev, + lip_dev->magic); + goto wplip_bh_transmit_exit; + } + + lip_link->cur_tx=lip_dev; + } + + for (;;){ + + if (--timeout_cnt == 0){ + DEBUG_EVENT("%s: LipDev TxBH Time squeeze\n",lip_link->name); + goto wplip_bh_transmit_exit; + } + + if (wan_test_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical)){ + goto wplip_bh_transmit_skip; + } + + skb=wan_skb_dequeue(&lip_dev->tx_queue); + if (skb){ + int len=wan_skb_len(skb); + + err=wplip_data_tx_down(lip_link,skb); + if (err != 0){ + wan_skb_queue_head(&lip_dev->tx_queue,skb); + wan_set_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); + goto wplip_bh_transmit_exit; + } + + lip_dev->ifstats.tx_packets++; + lip_dev->ifstats.tx_bytes += len; + + } + + if (WAN_NETIF_QUEUE_STOPPED(lip_dev->common.dev)){ + if (lip_dev->common.usedby == API){ +#warning "NENAD" + DEBUG_EVENT("%s: Api waking stack!\n",lip_dev->name); + WAN_NETIF_START_QUEUE(lip_dev->common.dev); +#if defined(__LINUX__) + wan_wakeup_api(lip_dev); +#endif + }else if (lip_dev->common.lip){ /*STACK*/ + WAN_NETIF_START_QUEUE(lip_dev->common.dev); + wplip_kick(lip_dev->common.lip,0); + + }else{ + WAN_NETIF_WAKE_QUEUE (lip_dev->common.dev); + } + } + + if (wan_skb_queue_len(&lip_dev->tx_queue)){ + wan_set_bit(WPLIP_MORE_LINK_TX,&lip_link->tq_working); + } + + wplip_prot_kick(lip_link,lip_dev); + +wplip_bh_transmit_skip: + + lip_dev=WAN_LIST_NEXT(lip_dev,list_entry); + if (lip_dev == NULL){ + lip_dev=WAN_LIST_FIRST(&lip_link->list_head_ifdev); + } + + if (lip_dev == lip_link->cur_tx){ + /* We went through the whole list */ + break; + } + + } + +wplip_bh_transmit_exit: + + lip_link->cur_tx=lip_dev; + +wplip_bh_link_transmit_exit: + + if (wan_skb_queue_len(&lip_link->tx_queue)){ + wan_set_bit(WPLIP_MORE_LINK_TX,&lip_link->tq_working); + } + + if (wan_test_bit(WPLIP_MORE_LINK_TX,&lip_link->tq_working)){ + return 1; + } + + return 0; + +} + + +static int wplip_retrigger_bh(wplip_link_t *lip_link) +{ + if (wan_test_bit(WPLIP_MORE_LINK_TX, &lip_link->tq_working) || + wan_skb_queue_len(&lip_link->rx_queue)){ + return wplip_trigger_bh(lip_link); + } +#if 0 + if (gdbg_flag){ + DEBUG_EVENT("%s: Not triggered\n", __FUNCTION__); + } +#endif + return -EINVAL; +} + + +#if defined(__LINUX__) +void wplip_link_bh(unsigned long data) +#else +void wplip_link_bh(void* data, int pending) +#endif +{ + wplip_link_t *lip_link = (wplip_link_t *)data; +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + wan_smp_flag_t s; +#endif + + DEBUG_TEST("%s: Link BH\n",__FUNCTION__); + + if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)){ + DEBUG_EVENT("%s: Link down in BH\n",__FUNCTION__); + return; + } + +#if defined(__LINUX__) + wan_spin_lock(&lip_link->bh_lock); +#else + wan_spin_lock_irq(NULL, &s); +#endif + wan_set_bit(WPLIP_BH_RUNNING,&lip_link->tq_working); + + wplip_bh_receive(lip_link); + + wplip_bh_transmit(lip_link); + + wan_clear_bit(WPLIP_BH_RUNNING,&lip_link->tq_working); + + WAN_TASKLET_END((&lip_link->task)); + + wplip_retrigger_bh(lip_link); + +#if defined(__LINUX__) + wan_spin_unlock(&lip_link->bh_lock); +#else + wan_spin_unlock_irq(NULL, &s); +#endif + +} + diff --git a/patches/kdrivers/src/lip/wanpipe_lip_iface.c b/patches/kdrivers/src/lip/wanpipe_lip_iface.c index 011a056..3d2a985 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_iface.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_iface.c @@ -833,13 +833,14 @@ int wplip_lipdev_prot_change_state(void *wplip_id,int state, lip_dev->common.state = state; WAN_NETIF_CARRIER_ON(lip_dev->common.dev); WAN_NETIF_START_QUEUE(lip_dev->common.dev); - wan_update_api_state(lip_dev); }else{ lip_dev->common.state = state; WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); } + wan_update_api_state(lip_dev); + wplip_trigger_bh(lip_dev->lip_link); }else if (lip_dev->common.lip) { /*STACK*/ diff --git a/patches/kdrivers/src/lip/wanpipe_lip_iface.c~ b/patches/kdrivers/src/lip/wanpipe_lip_iface.c~ new file mode 100644 index 0000000..d031cd1 --- /dev/null +++ b/patches/kdrivers/src/lip/wanpipe_lip_iface.c~ @@ -0,0 +1,1538 @@ +/************************************************************* + * wanpipe_lip.c WANPIPE Link Interface Protocol Layer (LIP) + * + * + * + * =========================================================== + * + * Dec 02 2003 Nenad Corbic Initial Driver + */ + + +/*============================================================= + * Includes + */ + +#if defined(__FreeBSD__) || defined(__OpenBSD__) +#include +#elif defined(__LINUX__) +#include +#endif + +/*============================================================= + * Definitions + */ + + +/*============================================================= + * Global Parameters + */ +/* Function interface between LIP layer and kernel */ +extern wan_iface_t wan_iface; + +struct wplip_link_list list_head_link; +wan_rwlock_t wplip_link_lock; +unsigned char wplip_link_num[MAX_LIP_LINKS]; +#if 0 +int gdbg_flag=0; +#endif + +/*============================================================= + * Function Prototypes + */ + +static int wplip_if_unreg (netdevice_t *dev); +static int wplip_bind_link(void *lip_id,netdevice_t *dev); +static int wplip_unbind_link(void *lip_id,netdevice_t *dev); +static void wplip_disconnect(void *wplip_id,int reason); +static void wplip_connect(void *wplip_id,int reason); +static int wplip_rx(void *wplip_id, void *skb); +static int wplip_unreg(void *reg_ptr); + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +static void wplip_if_task (void *arg, int dummy); +#else +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +static void wplip_if_task (void *arg); +# else +static void wplip_if_task (struct work_struct *work); +# endif +#endif + +extern int register_wanpipe_lip_protocol (wplip_reg_t *lip_reg); +extern void unregister_wanpipe_lip_protocol (void); + + +/*============================================================= + * Global Module Interface Functions + */ + + +/*============================================================= + * wplip_register + * + * Description: + * + * Usedby: + */ +/* EXPORT_SYMBOL(wplip_register); */ +static int wplip_register (void **lip_link_ptr, wanif_conf_t *conf, char *devname) +{ + wplip_link_t *lip_link = (wplip_link_t*)*lip_link_ptr; + + /* Create the new X25 link for this Lapb + * connection */ + if (lip_link){ + return -EEXIST; + } + + lip_link = wplip_create_link(devname); + if (!lip_link){ + DEBUG_EVENT("%s: LIP register: Failed to create link\n", + MODNAME); + return -ENOMEM; + } + + DEBUG_TEST("%s: Registering LIP Link\n",lip_link->name); + + + if (conf){ + int err=wplip_reg_link_prot(lip_link,conf); + if (err){ + wplip_free_link(lip_link); + return err; + } + } + + wplip_insert_link(lip_link); + + lip_link->state = WAN_DISCONNECTED; + lip_link->carrier_state = WAN_DISCONNECTED; + + + lip_link->latency_qlen=100; + + + *lip_link_ptr = lip_link; + + return 0; +} + +/*============================================================== + * wplip_unreg + * + * Description: + * This function is called during system setup to + * remove the whole x25 link and all x25 svc defined + * within the x25 link. + * + * For each x25 link and x25 svc the proc file + * entry is removed. + * + * Usedby: + * Lapb layer. + */ + +static int wplip_unreg(void *lip_link_ptr) +{ + wplip_link_t *lip_link = (wplip_link_t*)lip_link_ptr; + wplip_dev_t *lip_dev; + wplip_dev_list_t *lip_dev_list_el; + int err; + + if (wplip_link_exists(lip_link) != 0){ + return -ENODEV; + } + +#ifdef WPLIP_TTY_SUPPORT + if (lip_link->tty_opt && lip_link->tty_open){ + tty_hangup(lip_link->tty); + return -EBUSY; + } +#endif + + wan_del_timer(&lip_link->prot_timer); + + wan_set_bit(WPLIP_LINK_DOWN,&lip_link->tq_working); + while((lip_dev = WAN_LIST_FIRST(&lip_link->list_head_ifdev)) != NULL){ + + DEBUG_EVENT("%s: Unregistering dev %s\n", + lip_link->name,lip_dev->name); + + + err=wplip_if_unreg(lip_dev->common.dev); + if (err<0){ + wan_clear_bit(WPLIP_LINK_DOWN,&lip_link->tq_working); + return err; + } + } + + + while((lip_dev_list_el = WAN_LIST_FIRST(&lip_link->list_head_tx_ifdev)) != NULL){ + + DEBUG_EVENT("%s: Unregistering master dev %s\n", + lip_link->name, + wan_netif_name(lip_dev_list_el->dev)); + + WAN_DEV_PUT(lip_dev_list_el->dev); + lip_dev_list_el->dev=NULL; + + WAN_LIST_REMOVE(lip_dev_list_el,list_entry); + lip_link->tx_dev_cnt--; + + wan_free(lip_dev_list_el); + lip_dev_list_el=NULL; + } + + + if (lip_link->protocol){ + wplip_unreg_link_prot(lip_link); + } + + wplip_remove_link(lip_link); + wplip_free_link(lip_link); + + return 0; +} + + +static int wplip_if_reg(void *lip_link_ptr, char *dev_name, wanif_conf_t *conf) +{ + wplip_link_t *lip_link = (wplip_link_t*)lip_link_ptr; + wplip_dev_t *lip_dev; + int usedby=0; + int err; + + if (!conf){ + DEBUG_EVENT("%s: LIP DEV: If Registartion without configuration!\n",dev_name); + return -EINVAL; + } + +#ifdef WPLIP_TTY_SUPPORT + if (lip_link->tty_opt){ + return 0; + } +#endif + + if (wplip_link_exists(lip_link) != 0){ + DEBUG_EVENT("%s: LIP: Invalid Link !\n", + dev_name); + return -EINVAL; + } + + if (dev_name == NULL){ + DEBUG_EVENT("%s: LIP: Invalid device name : NULL!\n", + lip_link->name); + return -EINVAL; + } + + if (!wplip_lipdev_exists(lip_link,dev_name)){ + DEBUG_EVENT("%s: LIP: Invalid lip link device %s!\n", + __FUNCTION__,dev_name); + return -EEXIST; + } + + if(strcmp(conf->usedby, "API") == 0) { + usedby = API; + }else if(strcmp(conf->usedby, "WANPIPE") == 0){ + usedby = WANPIPE; + }else if(strcmp(conf->usedby, "STACK") == 0){ + usedby = STACK; + }else if(strcmp(conf->usedby, "BRIDGE") == 0){ + usedby = BRIDGE; + }else if(strcmp(conf->usedby, "BRIDGE_NODE") == 0){ + usedby = BRIDGE_NODE; +#if defined(__OpenBSD__) + }else if(strcmp(conf->usedby, "TRUNK") == 0){ + usedby = TRUNK; +#endif + }else{ + DEBUG_EVENT( "%s: LIP device invalid 'usedby': %s\n", + dev_name, conf->usedby); + return -EINVAL; + } + + if ((lip_dev = wplip_create_lipdev(dev_name, usedby)) == NULL){ + DEBUG_EVENT("%s: LIP: Failed to create lip priv device %s\n", + lip_link->name,dev_name); + return -ENOMEM; + } + +#if defined(__LINUX__) + if (conf->mtu){ + lip_dev->common.dev->mtu = conf->mtu; + } +#endif + + WAN_HOLD(lip_link); + lip_dev->lip_link = lip_link; + lip_dev->protocol = conf->protocol; + lip_dev->common.usedby = usedby; + lip_dev->common.state = WAN_DISCONNECTED; + WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); + +#if defined(__LINUX__) + if (conf->true_if_encoding){ + DEBUG_EVENT("%s: LIP: Setting IF Type to Broadcast\n",dev_name); + lip_dev->common.dev->flags &= ~IFF_POINTOPOINT; + lip_dev->common.dev->flags |= IFF_BROADCAST; + } +#endif + + switch (usedby){ + + case API: + wan_reg_api(lip_dev, lip_dev->common.dev, lip_link->name); + DEBUG_EVENT( "%s: Running in API mode\n", + lip_dev->name); + break; + case WANPIPE: + DEBUG_EVENT( "%s: Running in WANPIPE mode\n", + lip_dev->name); + break; + case STACK: + DEBUG_EVENT( "%s: Running in STACK mode\n", + lip_dev->name); + break; + + case BRIDGE: + DEBUG_EVENT( "%s: Running in BRIDGE mode\n", + lip_dev->name); + break; + + case BRIDGE_NODE: + DEBUG_EVENT( "%s: Running in BRIDGE Node mode\n", + lip_dev->name); + break; + + case TRUNK: + DEBUG_EVENT( "%s: Running in TRUNK mode\n", + lip_dev->name); + break; + + default: + DEBUG_EVENT( "%s: LIP device invalid 'usedby': %s\n", + lip_dev->name, conf->usedby); + __WAN_PUT(lip_link); + lip_dev->lip_link = NULL; + wplip_free_lipdev(lip_dev); + return -EINVAL; + } + + lip_dev->ipx_net_num = conf->network_number; + if (lip_dev->ipx_net_num) { + DEBUG_EVENT("%s: IPX Network Number = 0x%lX\n", + lip_dev->name, lip_dev->ipx_net_num); + } + + lip_dev->max_mtu_sz=MAX_TX_BUF; + lip_dev->max_mtu_sz_orig=MAX_TX_BUF; + + err=wplip_reg_lipdev_prot(lip_dev,conf); + if (err){ + __WAN_PUT(lip_link); + lip_dev->lip_link = NULL; + wplip_free_lipdev(lip_dev); + return err; + } + + wplip_insert_lipdev(lip_link,lip_dev); + WAN_TASKQ_INIT((&lip_dev->if_task),0,wplip_if_task,lip_dev); + + err=wplip_open_lipdev_prot(lip_dev); + if (err){ + wplip_remove_lipdev(lip_link,lip_dev); + __WAN_PUT(lip_link); + lip_dev->lip_link = NULL; + wplip_free_lipdev(lip_dev); + return err; + } + +#ifdef __LINUX__ + if (conf->if_down && usedby != API && usedby != STACK){ + wan_set_bit(DYN_OPT_ON,&lip_dev->interface_down); + DEBUG_EVENT("%s: Dynamic interface configuration enabled\n", + dev_name); + }else{ + wan_clear_bit(DYN_OPT_ON,&lip_dev->interface_down); + } + lip_link->latency_qlen=lip_dev->common.dev->tx_queue_len; +#endif + + if (lip_link->state == WAN_CONNECTED){ + DEBUG_TEST("%s: LIP CREATE Link already on!\n", + lip_dev->name); + WAN_NETIF_CARRIER_ON(lip_dev->common.dev); + WAN_NETIF_WAKE_QUEUE(lip_dev->common.dev); + wplip_trigger_bh(lip_dev->lip_link); + } + + DEBUG_TEST("%s: LIP LIPDEV Created %p Magic 0x%lX\n", + lip_link->name, + lip_dev, + lip_dev->magic); + return 0; +} + +/*============================================================== + * wplip_if_unreg + * + * Description: + * This function is called during system setup to + * remove the x25 link and each x25 svc defined + * in the wanpipe configuration file. + * + * For each x25 link and x25 svc the proc file + * entry is removed. + * + * Usedby: + * Lapb layer. + */ + +static int wplip_if_unreg (netdevice_t *dev) +{ + wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); + wplip_link_t *lip_link = NULL; + wplip_link_t *stack_lip_link = NULL; + wan_smp_flag_t flags; + + if (!lip_dev) + return -ENODEV; + + if (WAN_NETIF_UP(dev)){ + DEBUG_EVENT("%s: Failed to unregister: Device UP!\n", + wan_netif_name(dev)); + return -EBUSY; + } + + lip_link = lip_dev->lip_link; + + if (wplip_link_exists(lip_link) != 0){ + DEBUG_EVENT("%s: Failed to unregister: no link device\n", + wan_netif_name(dev)); + return -ENODEV; + } + + /* Check for a Higher Lip Link layer attached + * to this device. If exists, call unregister to + * remove it before unregistering this device */ + stack_lip_link=lip_dev->common.lip; /*STACK*/ + if (stack_lip_link){ + int err; + DEBUG_TEST("%s: IF UNREG: Calling Top Layer LIP UNREG\n", + lip_dev->name); + err=wplip_unreg(stack_lip_link); + if (err){ + return err; + } + } + + wplip_close_lipdev_prot(lip_dev); + + wan_set_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical); + wan_clear_bit(WAN_DEV_READY,&lip_dev->interface_down); + + + wan_spin_lock_irq(&lip_link->bh_lock,&flags); + lip_link->cur_tx=NULL; + wan_skb_queue_purge(&lip_dev->tx_queue); + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + + DEBUG_EVENT("%s: Unregistering LIP device\n", + wan_netif_name(dev)); + + if (lip_dev->common.prot_ptr){ + wplip_unreg_lipdev_prot(lip_dev); + } + + if (lip_dev->common.usedby == API){ + wan_unreg_api(lip_dev, lip_link->name); + } + + wplip_remove_lipdev(lip_link,lip_dev); + + __WAN_PUT(lip_dev->lip_link); + lip_dev->lip_link=NULL; + + wplip_free_lipdev(lip_dev); + + return 0; +} + + + +static int wplip_bind_link(void *lip_id,netdevice_t *dev) +{ + + wplip_link_t *lip_link = (wplip_link_t*)lip_id; + wplip_dev_list_t *lip_dev_list_el; + wan_smp_flag_t flags; + + if (!lip_id){ + return -ENODEV; + } + + if (wplip_link_exists(lip_link) != 0){ + return -ENODEV; + } + + if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)){ + return -ENETDOWN; + } + + lip_dev_list_el=wan_malloc(sizeof(wplip_dev_list_t)); + memset(lip_dev_list_el,0,sizeof(wplip_dev_list_t)); + + lip_dev_list_el->magic=WPLIP_MAGIC_DEV_EL; + + WAN_DEV_HOLD(dev); + + lip_dev_list_el->dev=dev; + + wan_spin_lock_irq(&lip_link->bh_lock,&flags); + + WAN_LIST_INSERT_HEAD(&lip_link->list_head_tx_ifdev,lip_dev_list_el,list_entry); + lip_link->tx_dev_cnt++; + + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + + return 0; +} + +static int wplip_unbind_link(void *lip_id,netdevice_t *dev) +{ + wplip_link_t *lip_link = (wplip_link_t*)lip_id; + wplip_dev_list_t *lip_dev_list_el=NULL; + wan_smp_flag_t flags; + int err=-ENODEV; + + if (!lip_id){ + return -EFAULT; + } + + if (wplip_link_exists(lip_link) != 0){ + return -EFAULT; + } + + + wan_spin_lock_irq(&lip_link->bh_lock,&flags); + + WAN_LIST_FOREACH(lip_dev_list_el,&lip_link->list_head_tx_ifdev,list_entry){ + if (lip_dev_list_el->dev == dev){ + WAN_LIST_REMOVE(lip_dev_list_el,list_entry); + lip_link->tx_dev_cnt--; + err=0; + break; + } + } + + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + + if (err==0){ + WAN_DEV_PUT(lip_dev_list_el->dev); + lip_dev_list_el->dev=NULL; + wan_free(lip_dev_list_el); + } + + return err; +} + + + + + +/*============================================================== + * wplip_rx + * + * Description: + * + * + * Usedby: + * Lower layer to pass us an rx packet. + */ + +static int wplip_rx(void *wplip_id, void *skb) +{ + wplip_link_t *lip_link = (wplip_link_t*)wplip_id; + + DEBUG_RX("%s: LIP LINK %s() pkt=%d %p\n", + lip_link->name,__FUNCTION__, + wan_skb_len(skb), + skb); + + if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)){ + return -ENODEV; + } + +#ifdef WPLIP_TTY_SUPPORT + if (lip_link->tty_opt){ + if (lip_link->tty && lip_link->tty_open){ + wplip_tty_receive(lip_link,skb); + wanpipe_tty_trigger_poll(lip_link); + return 0; + }else{ + return -ENODEV; + } + } +#endif + + if (wan_skb_queue_len(&lip_link->rx_queue) > MAX_RX_Q){ + DEBUG_TEST("%s: Critical Rx Error: Rx buf overflow 0x%lX!\n", + lip_link->name, + lip_link->tq_working); + wplip_trigger_bh(lip_link); + return -ENOBUFS; + } + + wan_skb_queue_tail(&lip_link->rx_queue,skb); + wplip_trigger_bh(lip_link); + + return 0; +} + +/*============================================================== + * wplip_data_rx_up + * + * Description: + * This function is used to pass data to the upper + * layer. If the lip dev is used by TCP/IP the packet + * is passed up the the TCP/IP stack, otherwise + * it is passed to the upper protocol layer. + * + * Locking: + * This function will ALWAYS get called from + * the BH handler with the bh_lock, thus + * its protected. + * + * Usedby: + */ + +int wplip_data_rx_up(wplip_dev_t* lip_dev, void *skb) +{ + int len=wan_skb_len(skb); + + DEBUG_TEST("LIP LINK %s() pkt=%i\n", + __FUNCTION__,wan_skb_len(skb)); + +#if 0 + DEBUG_EVENT("%s: %s() Packet Len=%d (DEBUG DROPPED)\n", + lip_dev->name, __FUNCTION__,wan_skb_len(skb)); + + wan_skb_free(skb); + return 0; +#endif + + switch (lip_dev->common.usedby){ + +#if defined(__LINUX__) + case API: + { + unsigned char *buf; + int err; + + if (wan_skb_headroom(skb) < sizeof(wan_api_rx_hdr_t)){ + DEBUG_EVENT("%s: Critical Error Rx pkt Hdrm=%d < ApiHdrm=%d\n", + lip_dev->name,wan_skb_headroom(skb), + sizeof(wan_api_rx_hdr_t)); + wan_skb_free(skb); + break; + } + + buf=wan_skb_push(skb,sizeof(wan_api_rx_hdr_t)); + memset(buf,0,sizeof(wan_api_rx_hdr_t)); + + ((netskb_t *)skb)->protocol = htons(PVC_PROT); + wan_skb_reset_mac_header(((netskb_t *)skb)); + wan_skb_reset_network_header(((netskb_t *)skb)); + ((netskb_t *)skb)->dev = lip_dev->common.dev; + ((netskb_t *)skb)->pkt_type = WAN_PACKET_DATA; + + if ((err=wan_api_rx(lip_dev,skb)) != 0){ +#if 0 + if (net_ratelimit()){ + DEBUG_EVENT("%s: Error: Rx Socket busy err=%i!\n", + lip_dev->name,err); + } +#endif + +#if 0 + #LAPB SHOULD PUSH BACK TO THE STACK + wan_skb_pull(skb,sizeof(wan_api_rx_hdr_t)); +#else + wan_skb_free(skb); +#endif + lip_dev->ifstats.rx_errors++; + return 1; + }else{ + lip_dev->ifstats.rx_packets++; + lip_dev->ifstats.rx_bytes+=len; + } + } + break; +#endif + + case STACK: + if (lip_dev->common.lip){ + int err=wplip_rx(lip_dev->common.lip,skb); + if (err){ + wan_skb_free(skb); + lip_dev->ifstats.rx_dropped++; + }else{ + lip_dev->ifstats.rx_packets++; + lip_dev->ifstats.rx_bytes+=len; + } + }else{ + wan_skb_free(skb); + lip_dev->ifstats.rx_dropped++; + } + + break; + default: + if (wan_iface.input && wan_iface.input(lip_dev->common.dev, skb) == 0){ + lip_dev->ifstats.rx_packets++; + lip_dev->ifstats.rx_bytes += len; + }else{ + wan_skb_free(skb); + lip_dev->ifstats.rx_dropped++; + } + + break; + } + return 0; +} + + +/*============================================================== + * wplip_data_tx_down + * + * Description: + * This function is used to pass data down to the + * lower layer. + * + * Locking: + * This function will ALWAYS get called from + * the BH handler with the bh_lock, thus + * its protected. + * + * Return Codes: + * + * 0: Packet send successful, lower layer + * will deallocate packet + * + * Non 0: Packet send failed, upper layer + * must handle the packet + * + */ + +int wplip_data_tx_down(wplip_link_t *lip_link, void *skb) +{ + wplip_dev_list_t *lip_dev_list_el; + netdevice_t *dev; + + DEBUG_TEST("%s: LIP LINK %s() pkt=%d\n", + lip_link->name,__FUNCTION__,wan_skb_len(skb)); + + + if (!lip_link->tx_dev_cnt){ + DEBUG_EVENT("%s: %s: Tx Dev List empty! dropping...\n", + __FUNCTION__,lip_link->name); + return -ENODEV; + } + + /* FIXME: + * For now, we can only transmit on a FIRST Tx device */ + lip_dev_list_el=WAN_LIST_FIRST(&lip_link->list_head_tx_ifdev); + if (!lip_dev_list_el){ + DEBUG_EVENT("%s: %s: Tx Dev List empty! dropping...\n", + __FUNCTION__,lip_link->name); + return -ENODEV; + } + + if (lip_dev_list_el->magic != WPLIP_MAGIC_DEV_EL){ + DEBUG_EVENT("%s: %s: Error: Invalid dev magic number! dropping...\n", + __FUNCTION__,lip_link->name); + return -EFAULT; + } + + dev=lip_dev_list_el->dev; + if (!dev){ + DEBUG_EVENT("%s: %s: Error: No dev! dropping...\n", + __FUNCTION__,lip_link->name); + return -ENODEV; + } + + if (WAN_NETIF_QUEUE_STOPPED(dev)){ + return -EBUSY; + } + +#if defined(__LINUX__) + if (lip_link->latency_qlen != dev->tx_queue_len) { + dev->tx_queue_len=lip_link->latency_qlen; + } + + return dev->hard_start_xmit(skb,dev); +#else + if (dev->if_output) return dev->if_output(dev, skb, NULL,NULL); + wan_skb_free(skb); + return 0; +#endif +} + +/*============================================================== + * wplip_link_prot_change_state + * + * Description: + * The lower layer calls this function, when it + * becomes disconnected. + */ + +int wplip_link_prot_change_state(void *wplip_id,int state, unsigned char *data, int len) +{ + wplip_link_t *lip_link = (wplip_link_t *)wplip_id; + + if (lip_link->prot_state != state){ + lip_link->prot_state=state; + + DEBUG_EVENT("%s: Lip Link Protocol State %s!\n", + lip_link->name, STATE_DECODE(state)); + + if (lip_link->prot_state == WAN_CONNECTED && + lip_link->carrier_state == WAN_CONNECTED){ + DEBUG_EVENT("%s: Lip Link Connected!\n", + lip_link->name); + lip_link->state = WAN_CONNECTED; + } + + if (lip_link->prot_state != WAN_CONNECTED){ + DEBUG_EVENT("%s: Lip Link Disconnected!\n", + lip_link->name); + lip_link->state = WAN_DISCONNECTED; + } + } + + return 0; +} + +int wplip_lipdev_prot_change_state(void *wplip_id,int state, + unsigned char *data, int len) +{ + wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; + + DEBUG_EVENT("%s: Lip Dev Prot State %s!\n", + lip_dev->name, STATE_DECODE(state)); + + lip_dev->common.state = state; + + if (lip_dev->common.usedby == API) { + + if (data && len){ + wplip_prot_oob(lip_dev,data,len); + } + + if (state == WAN_CONNECTED){ + lip_dev->common.state = state; + WAN_NETIF_CARRIER_ON(lip_dev->common.dev); + WAN_NETIF_START_QUEUE(lip_dev->common.dev); + }else{ + lip_dev->common.state = state; + WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); + WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); + } + + wan_update_api_state(lip_dev); + + wplip_trigger_bh(lip_dev->lip_link); + + }else if (lip_dev->common.lip) { /*STACK*/ + + if (state == WAN_CONNECTED){ + lip_dev->common.state = state; + WAN_NETIF_CARRIER_ON(lip_dev->common.dev); + WAN_NETIF_START_QUEUE(lip_dev->common.dev); + wplip_connect(lip_dev->common.lip,0); + }else{ + lip_dev->common.state = state; + WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); +#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) + WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); +#endif + wplip_disconnect(lip_dev->common.lip,0); + } + + }else{ + if (state == WAN_CONNECTED){ + lip_dev->common.state = state; + WAN_NETIF_CARRIER_ON(lip_dev->common.dev); + WAN_NETIF_WAKE_QUEUE(lip_dev->common.dev); + wplip_trigger_bh(lip_dev->lip_link); + }else{ + lip_dev->common.state = state; + WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); +#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) + WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); +#endif + } + wplip_trigger_if_task(lip_dev); + } + + return 0; +} + + +/*============================================================== + * wplip_connect + * + * Description: + * The lowyer layer calls this function, when it + * becomes connected. + */ + +static void wplip_connect(void *wplip_id,int reason) +{ + wplip_link_t *lip_link = (wplip_link_t *)wplip_id; + + if (lip_link->carrier_state != WAN_CONNECTED){ + wan_smp_flag_t flags; + + DEBUG_EVENT("%s: Lip Link Carrier Connected! \n", + lip_link->name); + + wan_spin_lock_irq(&lip_link->bh_lock,&flags); + wan_skb_queue_purge(&lip_link->tx_queue); + wan_skb_queue_purge(&lip_link->rx_queue); + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + + wplip_kick(lip_link,0); + + lip_link->carrier_state = WAN_CONNECTED; + } + + if (lip_link->prot_state == WAN_CONNECTED){ + + DEBUG_EVENT("%s: Lip Link Connected! \n", + lip_link->name); + + lip_link->state = WAN_CONNECTED; + } +} + +/*============================================================== + * wplip_disconnect + * + * Description: + * The lowyer layer calls this function, when it + * becomes disconnected. + */ + +static void wplip_disconnect(void *wplip_id,int reason) +{ + wplip_link_t *lip_link = (wplip_link_t *)wplip_id; + + if (lip_link->carrier_state != WAN_DISCONNECTED){ + DEBUG_EVENT("%s: Lip Link Carrier Disconnected!\n", + lip_link->name); + lip_link->carrier_state = WAN_DISCONNECTED; + } + + /* state = carrier_state & prot_state + * Therefore, the overall state is down */ + if (lip_link->state != WAN_DISCONNECTED){ + lip_link->state = WAN_DISCONNECTED; + DEBUG_EVENT("%s: Lip Link Disconnected!\n",lip_link->name); + } +} + + + +/*============================================================== + * wplip_kick + * + * Description: + */ + +void wplip_kick(void *wplip_id,int reason) +{ + wplip_link_t *lip_link = (wplip_link_t *)wplip_id; + +#warning "NENAD" + DEBUG_EVENT("%s: LIP Kick!\n", + lip_link->name); + +#ifdef WPLIP_TTY_SUPPORT + if (lip_link->tty_opt){ + wanpipe_tty_trigger_poll(lip_link); + }else +#endif + { + wan_clear_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); + wan_set_bit(WPLIP_KICK,&lip_link->tq_working); + wplip_kick_trigger_bh(lip_link); + } +} + +#define INTERFACES_FRM "%-15s| %-12s| %-6u| %-18s|\n" +static int wplip_get_if_status(void *wplip_id, void *mptr) +{ +#if defined(__LINUX__) + wplip_link_t *lip_link = (wplip_link_t *)wplip_id; + struct seq_file *m = (struct seq_file *)mptr; + wplip_dev_t *cur_dev; + unsigned long flag; + + WP_READ_LOCK(&lip_link->dev_list_lock,flag); + + WAN_LIST_FOREACH(cur_dev,&lip_link->list_head_ifdev,list_entry){ + PROC_ADD_LINE(m, + INTERFACES_FRM, + cur_dev->name, lip_link->name, + cur_dev->prot_addr, + STATE_DECODE(cur_dev->common.state)); + } + + WP_READ_UNLOCK(&lip_link->dev_list_lock,flag); + + return m->count; +#else + return -EINVAL; +#endif +} + + +int wplip_link_callback_tx_down(void *wplink_id, void *skb) +{ + wplip_link_t *lip_link = (wplip_link_t *)wplink_id; + + if (!lip_link || !skb){ + DEBUG_EVENT("%s: Assertion error lip_dev=NULL!\n", + __FUNCTION__); + return 1; + } + + DEBUG_TEST("%s:%s: Protocol Packet Len=%i\n", + lip_link->name,__FUNCTION__,wan_skb_len(skb)); + + + if (lip_link->carrier_state != WAN_CONNECTED){ + DEBUG_TEST("%s: %s() Error Lip Link Carrier not connected !\n", + lip_link->name,__FUNCTION__); + wan_skb_free(skb); + return 0; + } + + if (wan_skb_queue_len(&lip_link->tx_queue) >= MAX_TX_BUF){ + DEBUG_TEST("%s: %s() Error Protocol Tx queue full !\n", + lip_link->name,__FUNCTION__); + wplip_trigger_bh(lip_link); + return 1; + } + + wan_skb_unlink(skb); + wan_skb_queue_tail(&lip_link->tx_queue,skb); + wplip_trigger_bh(lip_link); + + return 0; +} +int wplip_callback_tx_down(void *wplip_id, void *skb) +{ + wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; + + if (!lip_dev){ + DEBUG_EVENT("%s: Assertion error lip_dev=NULL!\n", + __FUNCTION__); + return 1; + } + + if (!skb){ + int free_space=lip_dev->max_mtu_sz - wan_skb_queue_len(&lip_dev->tx_queue); + if (free_space < 0) { + return 0; + } else { + return free_space; + } + } + + + DEBUG_TEST("%s:%s: Packet Len=%i\n", + lip_dev->name,__FUNCTION__,wan_skb_len(skb)); + + + if (lip_dev->lip_link->carrier_state != WAN_CONNECTED){ + DEBUG_TEST("%s: %s() Error Lip Link Carrier not connected !\n", + lip_dev->name,__FUNCTION__); + wan_skb_free(skb); + lip_dev->ifstats.tx_carrier_errors++; + return 0; + } + + if (wan_skb_queue_len(&lip_dev->tx_queue) >= lip_dev->max_mtu_sz){ + wplip_trigger_bh(lip_dev->lip_link); + DEBUG_TEST("%s: %s() Error Tx queue full Kick=%d!\n", + lip_dev->name,__FUNCTION__, + wan_test_bit(WPLIP_BH_AWAITING_KICK,&lip_dev->lip_link->tq_working)); + return 1; + } + + wan_skb_unlink(skb); + wan_skb_queue_tail(&lip_dev->tx_queue,skb); + wplip_trigger_bh(lip_dev->lip_link); + + return 0; +} + +int wplip_callback_kick_prot_task (void *wplink_id) +{ + wplip_link_t *lip_link = (wplip_link_t *)wplink_id; + + if (!lip_link){ + DEBUG_EVENT("%s: Assertion error lip_dev=NULL!\n", + __FUNCTION__); + return 1; + } + + WAN_TASKQ_SCHEDULE((&lip_link->prot_task)); + + return 0; +} + +unsigned int wplip_get_ipv4_addr (void *wplip_id, int type) +{ + wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; +#ifdef __LINUX__ + + struct in_ifaddr *ifaddr; + struct in_device *in_dev; + + if ((in_dev = in_dev_get(lip_dev->common.dev)) == NULL){ + return 0; + } + + if ((ifaddr = in_dev->ifa_list)== NULL ){ + in_dev_put(in_dev); + return 0; + } + in_dev_put(in_dev); + + switch (type){ + + case WAN_LOCAL_IP: + return ifaddr->ifa_local; + break; + + case WAN_POINTOPOINT_IP: + return ifaddr->ifa_address; + break; + + case WAN_NETMASK_IP: + return ifaddr->ifa_mask; + break; + + case WAN_BROADCAST_IP: + return ifaddr->ifa_broadcast; + break; + default: + return 0; + } +#else + netdevice_t *ifp = NULL; + struct ifaddr *ifa = NULL; + struct sockaddr_in *si; + + ifp = lip_dev->common.dev; + for (ifa = WAN_TAILQ_FIRST(ifp); ifa; ifa = WAN_TAILQ_NEXT(ifa)){ + if (ifa->ifa_addr->sa_family == AF_INET) { + si = (struct sockaddr_in *)ifa->ifa_addr; + if (si) break; + } + } + + if (ifa) { + switch (type){ + case WAN_LOCAL_IP: + if (ifa->ifa_addr){ + return (satosin(ifa->ifa_addr))->sin_addr.s_addr; + } + break; + case WAN_POINTOPOINT_IP: + if (ifa->ifa_dstaddr){ + return (satosin(ifa->ifa_dstaddr))->sin_addr.s_addr; + } + break; + case WAN_NETMASK_IP: + if (ifa->ifa_netmask){ + return (satosin(ifa->ifa_netmask))->sin_addr.s_addr; + } + break; + case WAN_BROADCAST_IP: + if (ifa->ifa_broadaddr){ + return (satosin(ifa->ifa_broadaddr))->sin_addr.s_addr; + } + break; + } + } +#endif + return 0; +} + + +/* PROTOCOL MUST CALL THIS ONLY + * FROM A PROT TASK */ + +int wplip_set_ipv4_addr (void *wplip_id, + unsigned int local, + unsigned int remote, + unsigned int netmask, + unsigned int dns) +{ + wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; +#if defined(__LINUX__) + struct sockaddr_in *if_data; + struct ifreq if_info; + int err=0; + mm_segment_t fs; + netdevice_t *dev=lip_dev->common.dev; + + /* Setup a structure for adding/removing routes */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + if_data = (struct sockaddr_in *)&if_info.ifr_addr; + if_data->sin_addr.s_addr = local; + if_data->sin_family = AF_INET; + + fs = get_fs(); /* Save file system */ + set_fs(get_ds()); + err = wp_devinet_ioctl(SIOCSIFADDR, &if_info); + set_fs(fs); + + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data->sin_addr.s_addr = remote; + if_data->sin_family = AF_INET; + + fs = get_fs(); /* Save file system */ + set_fs(get_ds()); + err = wp_devinet_ioctl(SIOCSIFDSTADDR, &if_info); + set_fs(fs); + + return 0; +#else + netdevice_t *ifp = NULL; + struct ifaddr *ifa = NULL; + struct sockaddr_in *si = NULL; + + ifp = lip_dev->common.dev; + for (ifa = WAN_TAILQ_FIRST(ifp); ifa; ifa = WAN_TAILQ_NEXT(ifa)){ + if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET){ + si = (struct sockaddr_in *)ifa->ifa_addr; + if (si) break; + } + } + if (ifa && si){ + int error; +#if defined(__FreeBSD__) + struct in_ifaddr *ia; +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 103080000) + struct sockaddr_in new_sin = *si; + + new_sin.sin_addr.s_addr = htonl(src); + error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 1); +#else + /* delete old route */ + error = rtinit(ifa, (int)RTM_DELETE, RTF_HOST); + + /* set new address */ + si->sin_addr.s_addr = local; +#if defined(__FreeBSD__) + ia = ifatoia(ifa); + LIST_REMOVE(ia, ia_hash); + LIST_INSERT_HEAD(INADDR_HASH(si->sin_addr.s_addr), ia, ia_hash); +#endif +#if 0 + /* Local IP address */ + si = (struct sockaddr_in*)ifa->ifa_addr; + if (si){ + /* write new local IP address */ + si->sin_addr.s_addr = local; + } +#endif + /* Remote IP address */ + si = (struct sockaddr_in*)ifa->ifa_dstaddr; + if (si){ + /* write new remote IP address */ + si->sin_addr.s_addr = remote; + } + /* Netmask */ + si = (struct sockaddr_in*)ifa->ifa_netmask; + if (si){ + /* write new remote IP address */ + si->sin_addr.s_addr = htonl(0xFFFFFFFC); + } + + /* add new route */ + error = rtinit(ifa, (int)RTM_ADD, RTF_HOST); +#endif + } + return 0; +#endif +} + +void wplip_add_gateway(void *wplip_id) +{ + +#if 0 + wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; +#endif + return; +} + + +int wplip_set_hw_idle_frame (void *liplink_ptr, unsigned char *data, int len) +{ + + wplip_link_t *lip_link = (wplip_link_t *)liplink_ptr; + + if (!lip_link){ + DEBUG_EVENT("%s: Assertion error lip_dev=NULL!\n", + __FUNCTION__); + return 1; + } + + DEBUG_EVENT("%s: Warning: %s Not supported!\n", + lip_link->name,__FUNCTION__); + + return 0; +} + + +/*************************************************************** + * Private Device Functions + */ + +#ifdef __LINUX__ +static int wplip_change_dev_flags (netdevice_t *dev, unsigned flags) +{ + struct ifreq if_info; + mm_segment_t fs = get_fs(); + int err; + + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + if_info.ifr_flags = flags; + + set_fs(get_ds()); /* get user space block */ + err = wp_devinet_ioctl(SIOCSIFFLAGS, &if_info); + set_fs(fs); + + return err; +} +#endif + + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +static void wplip_if_task (void *arg, int dummy) +#else +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +static void wplip_if_task (void *arg) +# else +static void wplip_if_task (struct work_struct *work) +# endif +#endif +{ +#if defined(__LINUX__) + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) + wplip_dev_t *lip_dev=(wplip_dev_t *)container_of(work, wplip_dev_t, if_task); +#else + wplip_dev_t *lip_dev=(wplip_dev_t *)arg; +#endif + wplip_link_t *lip_link; + netdevice_t *dev; + + if (!lip_dev || !lip_dev->common.dev){ + return; + } + + if (wan_test_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical)){ + return; + } + + if (!wan_test_bit(DYN_OPT_ON,&lip_dev->interface_down) || + !wan_test_bit(WAN_DEV_READY,&lip_dev->interface_down)){ + return; + } + + DEBUG_TEST("%s:%d: Device %s\n",__FUNCTION__,__LINE__,lip_dev->name); + + lip_link = lip_dev->lip_link; + dev=lip_dev->common.dev; + + switch (lip_dev->common.state){ + + case WAN_DISCONNECTED: + + /* If the dynamic interface configuration is on, and interface + * is up, then bring down the netowrk interface */ + + if (wan_test_bit(DYN_OPT_ON,&lip_dev->interface_down) && + !wan_test_bit(DEV_DOWN, &lip_dev->interface_down) && + dev->flags & IFF_UP){ + + DEBUG_EVENT("%s: Interface %s down.\n", + lip_link->name,dev->name); + wplip_change_dev_flags(dev,(dev->flags&~IFF_UP)); + wan_set_bit(DEV_DOWN,&lip_dev->interface_down); + + } + + break; + + case WAN_CONNECTED: + + /* In SMP machine this code can execute before the interface + * comes up. In this case, we must make sure that we do not + * try to bring up the interface before dev_open() is finished */ + + + /* DEV_DOWN will be set only when we bring down the interface + * for the very first time. This way we know that it was us + * that brought the interface down */ + + if (wan_test_bit(DYN_OPT_ON,&lip_dev->interface_down) && + wan_test_bit(DEV_DOWN, &lip_dev->interface_down) && + !(dev->flags & IFF_UP)){ + + DEBUG_EVENT("%s: Interface %s up.\n", + lip_link->name,dev->name); + wplip_change_dev_flags(dev,(dev->flags|IFF_UP)); + wan_clear_bit(DEV_DOWN,&lip_dev->interface_down); + } + + break; + } + +#endif + +} + +void wplip_trigger_if_task(wplip_dev_t *lip_dev) +{ + + if (wan_test_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical)){ + return; + } + + if (wan_test_bit(DYN_OPT_ON,&lip_dev->interface_down) && + wan_test_bit(WAN_DEV_READY,&lip_dev->interface_down)){ + WAN_TASKQ_SCHEDULE((&lip_dev->if_task)); + } + + return; +} + +/*************************************************************** + * Module Interface Functions + * + */ + +/*============================================================== + * wanpipe_lip_init + * + * Description: + * This function is called on module startup. + * (ex: modprobe wanpipe_lip) + * + * Register the lip callback functions to the + * wanmain which are used by the socket or + * upper layer. + */ + + +static unsigned char wplip_fullname[]="WANPIPE(tm) L.I.P Network Layer"; +static unsigned char wplip_copyright[]="(c) 1995-2004 Sangoma Technologies Inc."; + +int wanpipe_lip_init(void*); +int wanpipe_lip_exit(void*); + +int wanpipe_lip_init(void *arg) +{ + wplip_reg_t reg; + int err; + + if (WANPIPE_VERSION_BETA){ + DEBUG_EVENT("%s Beta %s.%s %s\n", + wplip_fullname, WANPIPE_VERSION, WANPIPE_SUB_VERSION,wplip_copyright); + }else{ + DEBUG_EVENT("%s Stable %s.%s %s\n", + wplip_fullname, WANPIPE_VERSION, WANPIPE_SUB_VERSION, wplip_copyright); + } + + err=wplip_init_prot(); + if (err){ + wplip_free_prot(); + return err; + } + + wplip_link_lock=RW_LOCK_UNLOCKED; + + memset(®,0,sizeof(wplip_reg_t)); + + reg.wplip_bind_link = wplip_bind_link; + reg.wplip_unbind_link = wplip_unbind_link; + + reg.wplip_if_reg = wplip_if_reg; + reg.wplip_if_unreg = wplip_if_unreg; + + reg.wplip_disconnect = wplip_disconnect; + reg.wplip_connect = wplip_connect; + + reg.wplip_rx = wplip_rx; + reg.wplip_kick = wplip_kick; + + reg.wplip_register = wplip_register; + reg.wplip_unreg = wplip_unreg; + + reg.wplip_get_if_status = wplip_get_if_status; + + register_wanpipe_lip_protocol(®); + + memset(&wplip_link_num,0,sizeof(wplip_link_num)); + + return 0; +} + +int wanpipe_lip_exit (void *arg) +{ + if (!WAN_LIST_EMPTY(&list_head_link)){ + DEBUG_EVENT("%s: Major error: List not empty!\n",__FUNCTION__); + } + + unregister_wanpipe_lip_protocol(); + wplip_free_prot(); + + DEBUG_EVENT("WANPIPE L.I.P: Unloaded\n"); + return 0; +} + +#if 0 +MODULE_AUTHOR("Nenad Corbic "); +MODULE_DESCRIPTION("Wanpipe L.I.P Network Layer - Sangoma Tech. Copyright 2004"); +MODULE_LICENSE("GPL"); +module_init(wanpipe_lip_init); +module_exit(wanpipe_lip_exit); +#endif + +WAN_MODULE_DEFINE( + wanpipe_lip,"wanpipe_lip", + "Nenad Corbic ", + "Wanpipe L.I.P Network Layer - Sangoma Tech. Copyright 2004", + "GPL", + wanpipe_lip_init, wanpipe_lip_exit, NULL); +WAN_MODULE_DEPEND(wanpipe_lip, wanrouter, 1, + WANROUTER_MAJOR_VER, WANROUTER_MAJOR_VER); +WAN_MODULE_DEPEND(wanpipe_lip, wanpipe, 1, + WANPIPE_MAJOR_VER, WANPIPE_MAJOR_VER); + diff --git a/patches/kdrivers/src/lip/wanpipe_lip_netdev.c~ b/patches/kdrivers/src/lip/wanpipe_lip_netdev.c~ new file mode 100644 index 0000000..a47a1c9 --- /dev/null +++ b/patches/kdrivers/src/lip/wanpipe_lip_netdev.c~ @@ -0,0 +1,612 @@ +/************************************************************* + * wanpipe_lip_netdev.c WANPIPE Link Interface Protocol Layer (LIP) + * + * + * + * =========================================================== + * + * Mar 30 2004 Nenad Corbic Initial Driver + */ + + +/*============================================================= + * Includes + */ + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# include +#else +# include +#endif + + +/*============================================================= + * Definitions + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct rtentry* rt); +#endif + +char* get_master_dev_name(wplip_link_t *lip_link); + +/*============================================================== + * wplip_open_dev + * + * Description: + * This function enables the svc network device, and + * sets it up for data transfer. + * + * It is called by the kernel during interfaces + * startup via ifconfig: + * ex: ifconfig wp1_svc up + * + * If the network device contains IP data, its + * operation mode is set to TCP/IP otherwise, + * the opteration mode is API. + * + * Usedby: + * Kernel during ifconfig system call. + */ + +int wplip_open_dev(netdevice_t *dev) +{ + wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); + + if (!lip_dev || !lip_dev->lip_link){ + return -ENODEV; + } + +#if defined(__LINUX__) +# if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) + if (netif_running(dev)) + return -EBUSY; +# endif +#endif + + +#if 0 + /* Done in if register now, do it interface up down + * feature on 2.4 kernels */ + err=wplip_open_lipdev_prot(lip_dev); + if (err){ + return err; + } +#endif + +#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) + if (lip_dev->lip_link->state == WAN_CONNECTED){ + WAN_NETIF_CARRIER_ON(dev); + WAN_NETIF_WAKE_QUEUE(dev); + } +#else + if (lip_dev->lip_link->state == WAN_CONNECTED){ + WAN_NETIF_CARRIER_ON(dev); + } + WAN_NETIF_WAKE_QUEUE(dev); +#endif + + if (!wan_test_bit(WAN_DEV_READY,&lip_dev->interface_down)) { + wan_set_bit(WAN_DEV_READY,&lip_dev->interface_down); + wplip_trigger_if_task(lip_dev); + } + return 0; +} + +/*============================================================== + * wplip_stop_dev + * + * Description: + * This function disables the svc network device. + * + * It is called by the kernel during interfaces + * shutdown via ifconfig: + * ex: ifconfig wp1_svc down + * + * If the svc is in connected state, the call + * will be disconnected. + * + * Usedby: + * Kernel during ifconfig system call. + */ + +int wplip_stop_dev(netdevice_t *dev) +{ + + wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); + + if (!lip_dev || !lip_dev->lip_link){ + return 0; + } + +#ifdef WPLIP_TTY_SUPPORT + if (lip_dev->lip_link->tty_opt && lip_dev->lip_link->tty_open){ + tty_hangup(lip_dev->lip_link->tty); + return -EBUSY; + } +#endif + +#if 0 + /* Done in if register now, do it interface up down + * feature on 2.4 kernels */ + wplip_close_lipdev_prot(lip_dev); +#endif + + return 0; +} + + + +/*============================================================== + * wplip_ifstats + * + * Description: + * This fucntion interfaces the /proc file system + * to the svc device. The svc keeps protocol and + * packet statistcs. This function passes these + * statistics to the /proc file system. + * + * Usedby: + * Kernel /proc/net/dev file system + */ +static struct net_device_stats gstats; +struct net_device_stats* wplip_ifstats (netdevice_t *dev) +{ + wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); + + DEBUG_TEST("%s: LIP %s()\n", + wan_netif_name(dev),__FUNCTION__); + + if (lip_dev){ + return &lip_dev->ifstats; + } + + return &gstats; +} + + + +/*============================================================== + * wplip_if_send + * + * Description: + * Call back function used by the kernel or the + * upper protocol layer to transmit data for each + * svc withing the x25 link. + * + * Data can only be tranmsitted if the svc state + * is connected. + * + * If state != CONNECTED && If svc mode=TCP/IP + * place an x25 call and try to establish + * connection. + * + * If state != CONNECTED && If svc mode=API + * refuse the packet, and indicate to + * the upper layer that the connection has + * not been made. + * + * + * Usedby: + * Kernel TCP/IP stack or upper layers to transmit data. + */ + +#if defined(__LINUX__) +int wplip_if_send (netskb_t* skb, netdevice_t* dev) +#else +int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct rtentry* rt) +#endif +{ + wplip_dev_t *lip_dev =wplip_get_lipdev(dev); + wan_api_tx_hdr_t *api_tx_hdr =NULL; + int err, type; + + if (!lip_dev || !lip_dev->lip_link){ + WAN_NETIF_STOP_QUEUE(dev); + return 1; + } + + +#if 1 + if (lip_dev->common.state != WAN_CONNECTED){ +#else + if (lip_dev->lip_link->carrier_state != WAN_CONNECTED || + lip_dev->common.state != WAN_CONNECTED){ +#endif + +#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) + /* This causes a buffer starvations on some + * applications like OSPF, since packets are + * trapped in the Interface TX queue */ + + WAN_NETIF_STOP_QUEUE(dev); + wan_netif_set_ticks(dev, SYSTEM_TICKS); + ++lip_dev->ifstats.tx_carrier_errors; + return 1; +#else + wan_skb_free(skb); + lip_dev->ifstats.tx_carrier_errors++; + WAN_NETIF_START_QUEUE(dev); + wan_netif_set_ticks(dev, SYSTEM_TICKS); + return 0; +#endif + } + + /*if (wan_skb_check(skb)){ + ** if (wan_skb2buffer((void**)&skb)){ + ** wan_skb_free(skb); + ** lip_dev->ifstats.tx_errors++; + ** WAN_NETIF_START_QUEUE(dev); + ** wan_netif_set_ticks(dev, SYSTEM_TICKS); + ** return 0; + ** + ** } + **} */ + + if (lip_dev->common.usedby == API){ + if (wan_skb_len(skb) <= sizeof(wan_api_tx_hdr_t)){ + wan_skb_free(skb); + lip_dev->ifstats.tx_errors++; + WAN_NETIF_START_QUEUE(dev); + wan_netif_set_ticks(dev, SYSTEM_TICKS); + return 0; + } + api_tx_hdr=(wan_api_tx_hdr_t*)wan_skb_pull(skb,sizeof(wan_api_tx_hdr_t)); + + type = WPLIP_RAW; + }else{ +#if defined(__LINUX__) + type = wplip_decode_protocol(lip_dev,skb); +#else + type = wplip_decode_protocol(lip_dev,sa); +#endif + } + + + err=wplip_prot_tx(lip_dev, api_tx_hdr, skb, type); + switch (err){ + + case 0: + /* Packet queued ok */ + wan_netif_set_ticks(dev, SYSTEM_TICKS); + WAN_NETIF_START_QUEUE(dev); + err=0; + break; + + case 1: + /* Packet failed to queue layer busy */ +#warning "NENAD" + DEBUG_EVENT("%s: Api Dev BUSY!\n",lip_dev->name); + WAN_NETIF_STOP_QUEUE(dev); + err=1; + break; + + default: + /* Packet dropped due to error */ + WAN_NETIF_START_QUEUE(dev); + lip_dev->ifstats.tx_errors++; + wan_netif_set_ticks(dev, SYSTEM_TICKS); + wan_skb_free(skb); + err=0; + break; + } + + wplip_trigger_bh(lip_dev->lip_link); + +#if defined(__LINUX__) + if (lip_dev->protocol != WANCONFIG_LIP_ATM) { + if (dev->tx_queue_len < lip_dev->max_mtu_sz && + dev->tx_queue_len > 0) { + DEBUG_EVENT("%s: Resizing Tx Queue Len to %li\n", + lip_dev->name,dev->tx_queue_len); + lip_dev->max_mtu_sz = dev->tx_queue_len; + wplip_lipdev_latency_change(lip_dev->lip_link); + + } else if (dev->tx_queue_len > lip_dev->max_mtu_sz && + lip_dev->max_mtu_sz != lip_dev->max_mtu_sz_orig) { + DEBUG_EVENT("%s: Resizing Tx Queue Len to %i\n", + lip_dev->name,lip_dev->max_mtu_sz_orig); + lip_dev->max_mtu_sz = lip_dev->max_mtu_sz_orig; + wplip_lipdev_latency_change(lip_dev->lip_link); + } + } +#endif + + return err; +} + +#if defined(__LINUX__) +static void wplip_tx_timeout (netdevice_t *dev) +{ + wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); + wplip_link_t *lip_link = lip_dev->lip_link; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + +#if 0 + gdbg_flag=1; +#endif + wan_clear_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); + wplip_kick_trigger_bh(lip_link); + + WAN_NETIF_WAKE_QUEUE (dev); + + if (lip_dev->common.usedby == API){ + wan_update_api_state(lip_dev); + } + + wan_netif_set_ticks(dev, SYSTEM_TICKS); +} +#endif + +static int wplip_ioctl (netdevice_t *dev, struct ifreq *ifr, int cmd) +{ + + wplip_dev_t *lip_dev= wplip_get_lipdev(dev); + wplip_link_t *lip_link; + wan_smp_flag_t flags; + int err=0; + wan_udp_pkt_t *wan_udp_pkt; + + if (!lip_dev || !lip_dev->lip_link){ + DEBUG_EVENT("%s:%d: Assertion Error on lip_dev (%s)!\n", + __FUNCTION__,__LINE__, wan_netif_name(dev)); + return -EINVAL; + } + + lip_link = lip_dev->lip_link; + if (lip_link == NULL){ + DEBUG_EVENT("%s:%d: Assertion Error on lip_dev (%s)!\n", + __FUNCTION__,__LINE__, wan_netif_name(dev)); + return -EINVAL; + } + + switch (cmd){ + +#if defined(__LINUX__) + case SIOC_WANPIPE_BIND_SK: + if (ifr == NULL){ + err= -EINVAL; + break; + } + + wan_spin_lock_irq(&lip_link->bh_lock,&flags); + + if (lip_dev->common.usedby == API){ + dev->watchdog_timeo=HZ*60; + } + + err=wan_bind_api_to_svc(lip_dev,ifr->ifr_data); + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + break; + + case SIOC_WANPIPE_UNBIND_SK: + if (ifr == NULL){ + err= -EINVAL; + break; + } + + wan_spin_lock_irq(&lip_link->bh_lock,&flags); + err=wan_unbind_api_from_svc(lip_dev,ifr->ifr_data); + if (lip_dev->common.usedby == API && + lip_dev->protocol == WANCONFIG_XDLC){ + wplip_close_lipdev_prot(lip_dev); + } + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + break; + + case SIOC_WANPIPE_CHECK_TX: + case SIOC_ANNEXG_CHECK_TX: + err=0; + break; + + case SIOC_WANPIPE_DEV_STATE: + err = lip_dev->common.state; + break; + + case SIOC_ANNEXG_KICK: + break; +#endif + + case SIOC_WANPIPE_PIPEMON: + + wan_spin_lock_irq(&lip_link->bh_lock,&flags); + if (lip_dev->udp_pkt_len != 0){ + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + return -EBUSY; + } + lip_dev->udp_pkt_len = sizeof(wan_udp_hdr_t); + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + + wan_udp_pkt=(wan_udp_pkt_t*)&lip_dev->udp_pkt_data; + if (WAN_COPY_FROM_USER(&wan_udp_pkt->wan_udp_hdr,ifr->ifr_data,sizeof(wan_udp_hdr_t))){ + lip_dev->udp_pkt_len=0; + return -EFAULT; + } + + wan_spin_lock_irq(&lip_link->bh_lock,&flags); + + if(wan_udp_pkt->wan_udp_command == WAN_GET_MASTER_DEV_NAME){ + char* master_dev_name; + + master_dev_name = get_master_dev_name(lip_link); + if(master_dev_name == NULL){ + + wan_udp_pkt->wan_udp_return_code = 1; + wan_udp_pkt->wan_udp_data_len = 1; + }else{ + strncpy(&wan_udp_pkt->wan_udp_data[0], + master_dev_name, + strlen(master_dev_name)); + wan_udp_pkt->wan_udp_return_code = 0; + wan_udp_pkt->wan_udp_data_len = strlen(master_dev_name); + } + }else{ + if (wplip_prot_udp_mgmt_pkt(lip_dev,wan_udp_pkt) <= 0){ + lip_dev->udp_pkt_len=0; + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + return -EINVAL; + } + } + + if (lip_dev->udp_pkt_len > sizeof(wan_udp_pkt_t)){ + DEBUG_EVENT("%s: Error: Pipemon buf too bit on the way up! %i\n", + lip_dev->name,lip_dev->udp_pkt_len); + lip_dev->udp_pkt_len=0; + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + return -EINVAL; + } + + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + + /* This area will still be critical to other + * PIPEMON commands due to udp_pkt_len + * thus we can release the irq */ + + if (WAN_COPY_TO_USER(ifr->ifr_data,&wan_udp_pkt->wan_udp_hdr,sizeof(wan_udp_hdr_t))){ + lip_dev->udp_pkt_len=0; + return -EFAULT; + } + + lip_dev->udp_pkt_len=0; + return 0; + + case SIOC_WANPIPE_SNMP: + wplip_prot_udp_snmp_pkt(lip_dev,cmd,ifr); + return 0; + + case SIOC_WANPIPE_SNMP_IFSPEED: + DEBUG_EVENT("%s: SNMP Speed not supported on protocol interface!\n", + lip_dev->name); + return -1; + + default: + +#if defined(__LINUX__) + if (cmd >= SIOC_WANPIPE_DEVPRIVATE) + { + + wan_spin_lock_irq(&lip_link->bh_lock,&flags); + cmd-=SIOC_WANPIPE_DEVPRIVATE; + if (ifr == NULL){ + err=wplip_prot_ioctl(lip_dev,cmd,NULL); + }else{ + err=wplip_prot_ioctl(lip_dev,cmd,ifr->ifr_data); + } + wan_spin_unlock_irq(&lip_link->bh_lock,&flags); + + return err; + } +#endif + +# if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) + return 1; +#else + DEBUG_TEST("%s: Command %x not supported!\n", + lip_link->name,cmd); + return -EOPNOTSUPP; +#endif + } + + return err; + +} + +char* get_master_dev_name(wplip_link_t *lip_link) +{ + wplip_dev_list_t *lip_dev_list_el; + netdevice_t *dev; + + if (!lip_link->tx_dev_cnt){ + DEBUG_EVENT("%s: %s: Tx Dev List empty!\n", + __FUNCTION__,lip_link->name); + return NULL; + } + + lip_dev_list_el=WAN_LIST_FIRST(&lip_link->list_head_tx_ifdev); + if (!lip_dev_list_el){ + DEBUG_EVENT("%s: %s: Tx Dev List empty!\n", + __FUNCTION__,lip_link->name); + return NULL; + } + + if (lip_dev_list_el->magic != WPLIP_MAGIC_DEV_EL){ + DEBUG_EVENT("%s: %s: Error: Invalid dev magic number!\n", + __FUNCTION__,lip_link->name); + return NULL; + } + + dev=lip_dev_list_el->dev; + if (!dev){ + DEBUG_EVENT("%s: %s: Error: No dev!\n", + __FUNCTION__,lip_link->name); + return NULL; + } + + return wan_netif_name(dev); +} + +/*============================================================== + * wplip_if_init + * + * Description: + * During device registration, this function is + * called to fill in the call back functions + * used in nework device setup and operation. + * + * The kernel interfaces the driver, using the + * call back functions below. + * + * Usedby: + * Kernel during register_netdevice() in x25_register + * function. + */ +int wplip_if_init(netdevice_t *dev) +{ + wplip_dev_t* lip_dev= wplip_get_lipdev(dev); + +#if defined(__LINUX__) + lip_dev->common.is_netdev = 1; + lip_dev->common.iface.open = &wplip_open_dev; + lip_dev->common.iface.close = &wplip_stop_dev; + lip_dev->common.iface.send = &wplip_if_send; + lip_dev->common.iface.ioctl = &wplip_ioctl; + lip_dev->common.iface.tx_timeout= &wplip_tx_timeout; + lip_dev->common.iface.get_stats = &wplip_ifstats; + + return 0; +#else + DEBUG_EVENT("%s: Initialize network interface...\n", + wan_netif_name(dev)); + + lip_dev->common.is_netdev = 1; + lip_dev->common.iface.open = &wplip_open_dev; + lip_dev->common.iface.close = &wplip_stop_dev; + lip_dev->common.iface.output = &wplip_if_output; + lip_dev->common.iface.ioctl = &wplip_ioctl; + + dev->if_type = IFT_PPP; + dev->if_mtu = 1500; +#if 0 +/* Remove this later (wanpipe_bsd_iface.c doing this) */ + dev->if_output = NULL; + dev->if_start = &wplip_if_start; + dev->if_ioctl = NULL; /* &wplip_ioctl; */ + + /* Initialize media-specific parameters */ + dev->if_flags |= IFF_POINTOPOINT; + dev->if_flags |= IFF_NOARP; + + dev->if_mtu = 1500; + WAN_IFQ_SET_MAXLEN(&dev->if_snd, 100); + dev->if_snd.ifq_len = 0; + dev->if_type = IFT_PPP; +#endif + return 0; +#endif +} + + diff --git a/patches/kdrivers/src/net/Makefile b/patches/kdrivers/src/net/Makefile index 02da9ef..9730673 100644 --- a/patches/kdrivers/src/net/Makefile +++ b/patches/kdrivers/src/net/Makefile @@ -28,8 +28,13 @@ wanpipe-y := sdlamain.o ifneq (,$(ZAPDIR)) PRODUCT_DEFINES += -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE wanpipe-y += sdla_tdmv.o sdla_remora_tdmv.o + +ifneq (,$(wildcard $(ZAPHDLC))) +PRODUCT_DEFINES+= -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL +endif endif + wanpipe-y += sdla_ft1.o sdla_te1.o sdla_te3.o sdla_56k.o sdla_8te1.o wanpipe-y += wanpipe_tdm_api.o wanpipe-y += sdla_xilinx.o sdla_aft_te1.o aft_a104.o diff --git a/patches/kdrivers/src/net/Module.symvers b/patches/kdrivers/src/net/Module.symvers index 3325369..c9e240d 100644 --- a/patches/kdrivers/src/net/Module.symvers +++ b/patches/kdrivers/src/net/Module.symvers @@ -1,36 +1,36 @@ 0xf7567a8a wanpipe_api_buf_check /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0xf27fa082 wanpipe_lip_connect /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x3000ad78 sdla_register /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL -0xc0ef42f1 wp_sppp_input /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x57e6ed60 wanpipe_api_sock_rx /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x5f97184e wanrouter_proc_add_interface /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xc8a15fa6 sdla_register /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL +0xf7b65505 wp_sppp_input /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0xf08131ff wanpipe_api_sock_rx /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xeb489e63 wanrouter_proc_add_interface /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x59fb2682 sdla_hw_probe /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL 0x9a7a6658 wanpipe_lip_rx /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x8f31cdeb proc_router /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x580596c4 proc_router /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x94be524d register_wanec_iface /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x1036a1ab bind_api_listen_to_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xde2890ff bind_api_listen_to_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x524e2f20 register_wanpipe_fw_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x457621b6 register_wan_device /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xdad88768 wanrouter_proc_add_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xc9b2c3fb wp_sppp_attach /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x90a9f616 wp_sppp_detach /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x6eee717c register_wan_device net/wanrouter/wanrouter EXPORT_SYMBOL +0xd3eaa2bd wanrouter_proc_add_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x43891608 wp_sppp_attach /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0xf03004fc wp_sppp_detach /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL 0x56712648 wanpipe_ec_event_ctrl /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x7cd3c2bc wanpipe_ec_poll /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xf35baa74 wanrouter_proc_delete_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xf8093f70 wanrouter_proc_delete_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0xdfd0f6c6 sdla_get_hw_adptr_cnt /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL 0x10723cdb wanpipe_ec_register /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x1e82f485 wp_sppp_change_mtu /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x02364d27 wanrouter_encapsulate /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x136b2537 wan_skb_destructor /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xfa083e32 register_wanpipe_api_socket /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xa49dc980 wp_sppp_change_mtu /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0xd981a1fc wanrouter_encapsulate net/wanrouter/wanrouter EXPORT_SYMBOL +0xecdb7fad wan_skb_destructor /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x563e1e4c register_wanpipe_api_socket /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0xade2d0d7 sdla_get_hw_probe /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL -0xef48df91 proc_add_line /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x53c87809 proc_add_line /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x22a2999f sdla_unregister /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL -0x85c05713 wanrouter_type_trans /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xc98aebe6 wan_get_ip_address /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xfd74fadb wan_set_ip_address /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xd6fdd720 wanrouter_type_trans net/wanrouter/wanrouter EXPORT_SYMBOL +0x8506b552 wan_get_ip_address /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x5de7fb30 wan_set_ip_address /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x7d68ed07 protocol_disconnected /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xc5224c15 bind_api_to_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xfabc999d bind_api_to_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x38eb6851 unregister_wanpipe_api_socket /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0xaac011d2 wanpipe_lip_kick /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x3b604364 unbind_api_listen_from_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL @@ -39,18 +39,18 @@ 0x04df932b unregister_wanec_iface /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x19823ac0 wanpipe_ec_isr /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x13405f6b unregister_wanpipe_fw_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xe72f44cb wanpipe_api_listen_rx /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xe6bc2d6d wp_sppp_open /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x238f240b wp_sppp_reopen /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x72ddd010 wp_sppp_do_ioctl /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x85e65535 wanpipe_api_listen_rx /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x2bcba8b7 wp_sppp_open /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x656c1338 wp_sppp_reopen /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0xd6eb126f wp_sppp_do_ioctl /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL 0x5b7efb57 wanpipe_api_poll_wake /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x651a840a wan_add_gateway /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x805cbe1e wp_sppp_close /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x29d0266f wanrouter_proc_delete_interface /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x02fd3230 wan_add_gateway /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x03229b9c wp_sppp_close /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x77bcb76a wanrouter_proc_delete_interface /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x2f21a326 unregister_wanpipe_lip_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x0ebe03d1 unregister_wan_device /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x0ebe03d1 unregister_wan_device net/wanrouter/wanrouter EXPORT_SYMBOL 0x22317d82 wanpipe_lip_disconnect /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xed6a48f7 protocol_connected /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x0af8ffa5 protocol_connected /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL 0x53350bd4 wanpipe_ec_unregister /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x49a433d4 register_wanpipe_lip_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x00525339 protocol_connecting /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xab182e38 register_wanpipe_lip_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xd9baedd9 protocol_connecting /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL diff --git a/patches/kdrivers/src/net/aft_a104.c b/patches/kdrivers/src/net/aft_a104.c index dfe022c..7d46892 100644 --- a/patches/kdrivers/src/net/aft_a104.c +++ b/patches/kdrivers/src/net/aft_a104.c @@ -1731,8 +1731,12 @@ static int aft_hwec_reset(void *pcard, int reset) DEBUG_EVENT("%s: Clear Echo Canceller chip reset.\n", card->devname); - if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID/*card->adptr_type == A108_ADPTR_8TE1*/) { - aft_te1_write_cpld(card,0x00,0x07); + if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID) { + if(card->adptr_type == A108_ADPTR_8TE1){ + aft_te1_write_cpld(card,0x00,0x0F); + } else { + aft_te1_write_cpld(card,0x00,0x07); + } }else{ if (IS_T1_CARD(card)){ diff --git a/patches/kdrivers/src/net/sdla_8te1.c b/patches/kdrivers/src/net/sdla_8te1.c index c9e7a92..fce752c 100644 --- a/patches/kdrivers/src/net/sdla_8te1.c +++ b/patches/kdrivers/src/net/sdla_8te1.c @@ -81,6 +81,11 @@ /****************************************************************************** * DEFINES AND MACROS ******************************************************************************/ +#undef WANPIPE_IGNORE_T1_YELLOW +/* Dec 14, 2007 +** Disable all FE interrupt if Short Circuit condition detected! */ +#undef WAN_FE_SC_DISABLE_INTR + #define CLEAR_REG(sreg,ereg) { \ unsigned short reg; \ for(reg = sreg; reg < ereg; reg++){ \ @@ -165,7 +170,7 @@ #define WAN_TE1_FRAMED_ALARMS (WAN_TE_BIT_RED_ALARM | WAN_TE_BIT_OOF_ALARM) -#define WAN_TE1_UNFRAMED_ALARMS (WAN_TE_BIT_RED_ALARM) +#define WAN_TE1_UNFRAMED_ALARMS (WAN_TE_BIT_RED_ALARM | WAN_TE_BIT_LOS_ALARM) #define IS_T1_ALARM(alarm) \ (alarm & \ @@ -693,8 +698,13 @@ static int sdla_ds_te1_chip_config(void* pfe) WRITE_REG(REG_TMMR, 0x00); /* Enable Rx Framer */ WRITE_REG(REG_RMMR, BIT_RMMR_FRM_EN); - /* Enable Tx Framer */ - WRITE_REG(REG_TMMR, BIT_TMMR_FRM_EN); + if (IS_FE_TXTRISTATE(fe)){ + DEBUG_EVENT("%s: Tx Disabled (tri-state mode)\n", + fe->name); + }else{ + /* Enable Tx Framer */ + WRITE_REG(REG_TMMR, BIT_TMMR_FRM_EN); + } }else{ /* Clear Rx Framer soft reset */ WRITE_REG(REG_RMMR, BIT_RMMR_T1E1); @@ -702,8 +712,13 @@ static int sdla_ds_te1_chip_config(void* pfe) WRITE_REG(REG_TMMR, BIT_TMMR_T1E1); /* Enable Rx Framer */ WRITE_REG(REG_RMMR, (BIT_RMMR_FRM_EN | BIT_RMMR_T1E1)); - /* Enable Tx Framer */ - WRITE_REG(REG_TMMR, (BIT_TMMR_FRM_EN | BIT_TMMR_T1E1)); + if (IS_FE_TXTRISTATE(fe)){ + DEBUG_EVENT("%s: Tx Disabled (tri-state mode)\n", + fe->name); + }else{ + /* Enable Tx Framer */ + WRITE_REG(REG_TMMR, (BIT_TMMR_FRM_EN | BIT_TMMR_T1E1)); + } } if (IS_T1_FEMEDIA(fe)){ @@ -740,6 +755,15 @@ static int sdla_ds_te1_chip_config(void* pfe) WRITE_REG(REG_RCR1, value | BIT_RCR1_E1_RCRC4); value = READ_REG(REG_TCR1); WRITE_REG(REG_TCR1, value | BIT_TCR1_E1_TCRC4); + value = READ_REG(REG_TCR2); + WRITE_REG(REG_TCR2, value | BIT_TCR2_E1_AEBE); + break; + case WAN_FR_UNFRAMED: + /* Nov 23, 2007 UNFRM */ + value = READ_REG(REG_TCR1); + WRITE_REG(REG_TCR1, value | BIT_TCR1_E1_TTPT); + value = READ_REG(REG_RCR1); + WRITE_REG(REG_RCR1, value | BIT_RCR1_E1_SYNCE); break; default: DEBUG_EVENT("%s: Unsupported DS Frame mode (%X)\n", @@ -747,15 +771,6 @@ static int sdla_ds_te1_chip_config(void* pfe) return -EINVAL; } - if (IS_E1_FEMEDIA(fe)){ - switch(WAN_FE_FRAME(fe)){ - case WAN_FR_CRC4: - value = READ_REG(REG_TCR2); - WRITE_REG(REG_TCR2, value | BIT_TCR2_E1_AEBE); - break; - } - } - if (IS_E1_FEMEDIA(fe)){ sdla_ds_e1_set_sig_mode(fe, 0); } @@ -821,16 +836,33 @@ static int sdla_ds_te1_chip_config(void* pfe) } #endif if (IS_E1_FEMEDIA(fe)){ + //WRITE_REG(REG_E1TAF, 0x1B); + //WRITE_REG(REG_E1TNAF, 0x40); WRITE_REG(REG_E1TAF, 0x1B); - WRITE_REG(REG_E1TNAF, 0x40); + WRITE_REG(REG_E1TNAF, 0x5F); + WRITE_REG(REG_E1TSa4, 0x00); + WRITE_REG(REG_E1TSa5, 0x00); + WRITE_REG(REG_E1TSa6, 0x00); + WRITE_REG(REG_E1TSa7, 0x00); + WRITE_REG(REG_E1TSa8, 0x00); + WRITE_REG(REG_E1TSACR, 0x00); + if (WAN_FE_FRAME(fe) == WAN_FR_CRC4){ + WRITE_REG(REG_E1TSa4, 0xFF); + WRITE_REG(REG_E1TSa5, 0xFF); + WRITE_REG(REG_E1TSa6, 0xFF); + WRITE_REG(REG_E1TSa7, 0xFF); + WRITE_REG(REG_E1TSa8, 0xFF); + WRITE_REG(REG_E1TSACR, 0x1F); + } } - /* Set INIT_DONE */ - value = READ_REG(REG_RMMR); - WRITE_REG(REG_RMMR, value | BIT_RMMR_INIT_DONE); - /* Set INIT_DONE */ - value = READ_REG(REG_TMMR); - WRITE_REG(REG_TMMR, value | BIT_TMMR_INIT_DONE); + if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ + /* Set INIT_DONE (not unframed mode) */ + value = READ_REG(REG_RMMR); + WRITE_REG(REG_RMMR, value | BIT_RMMR_INIT_DONE); + value = READ_REG(REG_TMMR); + WRITE_REG(REG_TMMR, value | BIT_TMMR_INIT_DONE); + } /* T1/J1 or E1 */ if (IS_T1_FEMEDIA(fe)){ @@ -858,15 +890,19 @@ static int sdla_ds_te1_chip_config(void* pfe) value = 0x00; break; case WAN_T1_133_266: + case WAN_T1_110_220: value = BIT_LTITSR_L0; break; case WAN_T1_266_399: + case WAN_T1_220_330: value = BIT_LTITSR_L1; break; case WAN_T1_399_533: + case WAN_T1_330_440: value = BIT_LTITSR_L1 | BIT_LTITSR_L0; break; case WAN_T1_533_655: + case WAN_T1_550_660: value = BIT_LTITSR_L2; break; case WAN_E1_120: @@ -893,10 +929,51 @@ static int sdla_ds_te1_chip_config(void* pfe) value | BIT_LTITSR_TIMPL0); } - value = BIT_LRISMR_RSMS1 | BIT_LRISMR_RSMS0; + value = 0x00; if (WAN_TE1_HI_MODE(fe)){ value |= BIT_LRISMR_RMONEN; + switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ + case WAN_TE1_RX_SLEVEL_30_DB: + break; + case WAN_TE1_RX_SLEVEL_225_DB: + value |= BIT_LRISMR_RSMS0; + break; + case WAN_TE1_RX_SLEVEL_175_DB: + value |= BIT_LRISMR_RSMS1; + break; + case WAN_TE1_RX_SLEVEL_12_DB: + value |= (BIT_LRISMR_RSMS1 | BIT_LRISMR_RSMS0); + break; + default: /* set default value */ + fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_30_DB; + break; + } + DEBUG_EVENT("%s: Rx Sensitivity Gain %s (High Impedence mode).\n", + fe->name, + WAN_TE1_RX_SLEVEL_DECODE(fe->fe_cfg.cfg.te_cfg.rx_slevel)); + }else{ + switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ + case WAN_TE1_RX_SLEVEL_12_DB: + break; + case WAN_TE1_RX_SLEVEL_18_DB: + value |= BIT_LRISMR_RSMS0; + break; + case WAN_TE1_RX_SLEVEL_30_DB: + value |= BIT_LRISMR_RSMS1; + break; + case WAN_TE1_RX_SLEVEL_36_DB: + case WAN_TE1_RX_SLEVEL_43_DB: + value |= (BIT_LRISMR_RSMS1 | BIT_LRISMR_RSMS0); + break; + default: /* set default value */ + fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_12_DB; + break; + } + DEBUG_EVENT("%s: Rx Sensitivity Gain %s.\n", + fe->name, + WAN_TE1_RX_SLEVEL_DECODE(fe->fe_cfg.cfg.te_cfg.rx_slevel)); } + if (IS_T1_FEMEDIA(fe)){ WRITE_REG(REG_LRISMR, value | BIT_LRISMR_RIMPM0); }else{ @@ -1043,7 +1120,7 @@ static int sdla_ds_te1_config(void* pfe) wan_set_bit(TE_CONFIGURED,(void*)&fe->te_param.critical); /* Enable interrupts */ - sdla_ds_te1_intr_ctrl(fe, 0, WAN_TE_INTR_BASIC, WAN_FE_INTR_ENABLE, 0x00); + sdla_ds_te1_intr_ctrl(fe, 0, WAN_TE_INTR_GLOBAL, WAN_FE_INTR_ENABLE, 0x00); /* Enable manual update pmon counter */ sdla_ds_te1_intr_ctrl(fe, 0, WAN_TE_INTR_PMON, WAN_FE_INTR_MASK, 0x00); return 0; @@ -1215,31 +1292,46 @@ sdla_ds_te1_sigctrl(sdla_fe_t *fe, int sig_mode, unsigned long ch_map, int mode) /****************************************************************************** -** sdla_ds_t1_is_connected() +** sdla_ds_t1_is_alarm() ** ** Description: Verify T1 status. ** Arguments: ** Returns: 1 - the port is connected ** 0 - the port is disconnected ******************************************************************************/ -static int sdla_ds_t1_is_connected(sdla_fe_t *fe, unsigned long alarms) +static int sdla_ds_t1_is_alarm(sdla_fe_t *fe, unsigned long alarms) { - - if (alarms & WAN_TE1_FRAMED_ALARMS) return 0; - return 1; + /* NC: Bring the link down if we re in SC mode */ + if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + return 1; + } + return (alarms & WAN_TE1_FRAMED_ALARMS); } /****************************************************************************** -** sdla_ds_e1_is_connected() +** sdla_ds_e1_is_alarm() ** ** Description: Verify E1 status. ** Arguments: ** Returns: 1 - the port is connected ** 0 - the port is disconnected ******************************************************************************/ -static int sdla_ds_e1_is_connected(sdla_fe_t *fe, unsigned long alarms) +static int sdla_ds_e1_is_alarm(sdla_fe_t *fe, unsigned long alarms) { - if (alarms & WAN_TE1_FRAMED_ALARMS) return 0; - return 1; + if (WAN_FE_FRAME(fe) == WAN_FR_UNFRAMED){ + if (!fe->te_param.lb_mode && + (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_OC || + fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC || + fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_LOS)){ + return 1; + } + return (alarms & WAN_TE1_UNFRAMED_ALARMS); + } + + /* NC: Bring the link down if we re in SC mode */ + if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + return 1; + } + return (alarms & WAN_TE1_FRAMED_ALARMS); } /* @@ -1259,8 +1351,31 @@ static void sdla_ds_te1_set_status(sdla_fe_t* fe, unsigned long alarms) if (IS_T1_FEMEDIA(fe)){ - if (sdla_ds_t1_is_connected(fe, alarms)){ - sdla_ds_te1_clear_alarms(fe, WAN_TE_BIT_YEL_ALARM); + if (sdla_ds_t1_is_alarm(fe, alarms)){ + if (fe->fe_status != FE_DISCONNECTED){ + fe->fe_status = FE_DISCONNECTED; + } + }else{ + +#ifdef WANPIPE_IGNORE_T1_YELLOW +#warning "AFT IGNORING YELLOW ALARM!" +/* If we ignore yellow alarm, we will pass it up + to zaptel. We will be in connected state where + zaptel will be in alarm. Its a deadlock + condition + + This option can be compiled using Setup + script in case of some users that + have yellow alarm issues. + + Should never be used in ZAPTEL mode! +*/ + if (fe->fe_status != FE_CONNECTED){ + sdla_ds_te1_clear_alarms(fe, WAN_TE_BIT_YEL_ALARM); + fe->fe_status = FE_CONNECTED; + } +#else + //sdla_ds_te1_clear_alarms(fe, WAN_TE_BIT_YEL_ALARM); if (!(fe->fe_alarm & WAN_TE_BIT_YEL_ALARM)){ if (fe->fe_status != FE_CONNECTED){ fe->fe_status = FE_CONNECTED; @@ -1272,21 +1387,17 @@ static void sdla_ds_te1_set_status(sdla_fe_t* fe, unsigned long alarms) } fe->fe_status = FE_DISCONNECTED; } - }else{ +#endif + } + } else { + if (sdla_ds_e1_is_alarm(fe, alarms)){ if (fe->fe_status != FE_DISCONNECTED){ fe->fe_status = FE_DISCONNECTED; } - } - - } else { - if (sdla_ds_e1_is_connected(fe, alarms)){ + }else{ if (fe->fe_status != FE_CONNECTED){ fe->fe_status = FE_CONNECTED; } - } else { - if (fe->fe_status != FE_DISCONNECTED){ - fe->fe_status = FE_DISCONNECTED; - } } } @@ -1334,6 +1445,14 @@ static void sdla_ds_te1_set_status(sdla_fe_t* fe, unsigned long alarms) fe->te_param.status_cnt); } +#if defined(WAN_FE_SC_DISABLE_INTR) + if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + if (card->wandev.critical_event){ + card->wandev.critical_event(card, 0); + } + } +#endif + return; } @@ -1402,132 +1521,178 @@ static int sdla_ds_te1_print_alarms(sdla_fe_t* fe, unsigned int alarms) ** Arguments: ** Returns: */ -static unsigned int sdla_ds_te1_read_alarms(sdla_fe_t *fe, int action) +static unsigned int sdla_ds_te1_read_frame_alarms(sdla_fe_t *fe) { + unsigned int fr_alarm = fe->fe_alarm; + unsigned char rrts1 = READ_REG(REG_RRTS1); - if (IS_FE_ALARM_READ(action)){ - unsigned char rrts1 = READ_REG(REG_RRTS1); - unsigned char lrsr = READ_REG(REG_LRSR); - - DEBUG_TE1("%s: Alarm status = %02X (%X)\n", - fe->name, rrts1, fe->fe_alarm); - /* Framer alarms */ + DEBUG_TE1("%s: Framer Alarm status = %02X (%X)\n", + fe->name, rrts1, fr_alarm); + /* Framer alarms */ + //if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ if (rrts1 & BIT_RRTS1_RRAI){ - if (!(fe->fe_alarm & WAN_TE_BIT_RAI_ALARM)){ + if (!(fr_alarm & WAN_TE_BIT_RAI_ALARM)){ DEBUG_EVENT("%s: RAI alarm is ON\n", fe->name); } - fe->fe_alarm |= WAN_TE_BIT_RAI_ALARM; + fr_alarm |= WAN_TE_BIT_RAI_ALARM; }else{ - if (fe->fe_alarm & WAN_TE_BIT_RAI_ALARM){ + if (fr_alarm & WAN_TE_BIT_RAI_ALARM){ DEBUG_EVENT("%s: RAI alarm is OFF\n", fe->name); } - fe->fe_alarm &= ~WAN_TE_BIT_RAI_ALARM; + fr_alarm &= ~WAN_TE_BIT_RAI_ALARM; } - if (rrts1 & BIT_RRTS1_RAIS){ - if (!(fe->fe_alarm & WAN_TE_BIT_AIS_ALARM)){ - DEBUG_EVENT("%s: AIS alarm is ON\n", - fe->name); - } - fe->fe_alarm |= WAN_TE_BIT_AIS_ALARM; - }else{ - if (fe->fe_alarm & WAN_TE_BIT_AIS_ALARM){ - DEBUG_EVENT("%s: AIS alarm is OFF\n", - fe->name); - } - fe->fe_alarm &= ~WAN_TE_BIT_AIS_ALARM; + //} + if (rrts1 & BIT_RRTS1_RAIS){ + if (!(fr_alarm & WAN_TE_BIT_AIS_ALARM)){ + DEBUG_EVENT("%s: AIS alarm is ON\n", + fe->name); } - if (rrts1 & BIT_RRTS1_RLOS){ - if (!(fe->fe_alarm & WAN_TE_BIT_LOS_ALARM)){ - DEBUG_EVENT("%s: LOS alarm is ON\n", - fe->name); - } - fe->fe_alarm |= WAN_TE_BIT_LOS_ALARM; - }else{ - if (fe->fe_alarm & WAN_TE_BIT_LOS_ALARM){ - DEBUG_EVENT("%s: LOS alarm is OFF\n", - fe->name); - } - fe->fe_alarm &= ~WAN_TE_BIT_LOS_ALARM; + fr_alarm |= WAN_TE_BIT_AIS_ALARM; + }else{ + if (fr_alarm & WAN_TE_BIT_AIS_ALARM){ + DEBUG_EVENT("%s: AIS alarm is OFF\n", + fe->name); } + fr_alarm &= ~WAN_TE_BIT_AIS_ALARM; + } + if (rrts1 & BIT_RRTS1_RLOS){ + if (!(fr_alarm & WAN_TE_BIT_LOS_ALARM)){ + DEBUG_EVENT("%s: LOS alarm is ON\n", + fe->name); + } + fr_alarm |= WAN_TE_BIT_LOS_ALARM; + }else{ + if (fr_alarm & WAN_TE_BIT_LOS_ALARM){ + DEBUG_EVENT("%s: LOS alarm is OFF\n", + fe->name); + } + fr_alarm &= ~WAN_TE_BIT_LOS_ALARM; + } + if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ if (rrts1 & BIT_RRTS1_RLOF){ - if (!(fe->fe_alarm & WAN_TE_BIT_OOF_ALARM)){ + if (!(fr_alarm & WAN_TE_BIT_OOF_ALARM)){ DEBUG_EVENT("%s: OOF alarm is ON\n", - fe->name); + fe->name); } - fe->fe_alarm |= WAN_TE_BIT_OOF_ALARM; + fr_alarm |= WAN_TE_BIT_OOF_ALARM; }else{ - if (fe->fe_alarm & WAN_TE_BIT_OOF_ALARM){ + if (fr_alarm & WAN_TE_BIT_OOF_ALARM){ DEBUG_EVENT("%s: OOF alarm is OFF\n", - fe->name); + fe->name); } - fe->fe_alarm &= ~WAN_TE_BIT_OOF_ALARM; + fr_alarm &= ~WAN_TE_BIT_OOF_ALARM; + } + } + /* Aug 30, 2006 + ** Red alarm is either LOS or OOF alarms */ + if (IS_TE_OOF_ALARM(fr_alarm) || + IS_TE_LOS_ALARM(fr_alarm)){ + if (!(fr_alarm & WAN_TE_BIT_RED_ALARM)){ + DEBUG_EVENT("%s: RED alarm is ON\n", + fe->name); } - /* Aug 30, 2006 - ** Red alarm is either LOS or OOF alarms */ - if (IS_TE_OOF_ALARM(fe->fe_alarm) || - IS_TE_LOS_ALARM(fe->fe_alarm)){ - if (!(fe->fe_alarm & WAN_TE_BIT_RED_ALARM)){ - DEBUG_EVENT("%s: RED alarm is ON\n", - fe->name); - } - fe->fe_alarm |= WAN_TE_BIT_RED_ALARM; - }else{ - if (fe->fe_alarm & WAN_TE_BIT_RED_ALARM){ - DEBUG_EVENT("%s: RED alarm is OFF\n", - fe->name); - } - fe->fe_alarm &= ~WAN_TE_BIT_RED_ALARM; + fr_alarm |= WAN_TE_BIT_RED_ALARM; + }else{ + if (fr_alarm & WAN_TE_BIT_RED_ALARM){ + DEBUG_EVENT("%s: RED alarm is OFF\n", + fe->name); } + fr_alarm &= ~WAN_TE_BIT_RED_ALARM; + } + return fr_alarm; +} - /* LIU alarms */ - if (lrsr & BIT_LRSR_OCS){ - if (!(fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_OC)){ - DEBUG_EVENT("%s: Open Circuit is detected!\n", - fe->name); - } - fe->liu_alarm |= WAN_TE_BIT_LIU_ALARM_OC; - }else{ - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_OC){ - DEBUG_EVENT("%s: Open Circuit is cleared!\n", - fe->name); - } - fe->liu_alarm &= ~WAN_TE_BIT_LIU_ALARM_OC; +static unsigned int sdla_ds_te1_read_liu_alarms(sdla_fe_t *fe) +{ + unsigned int alarm = fe->liu_alarm; + unsigned char lrsr = READ_REG(REG_LRSR); + + DEBUG_TE1("%s: LIU Alarm status = %02X (%X)\n", + fe->name, lrsr1, alarm); + + /* LIU alarms */ + if (lrsr & BIT_LRSR_OCS){ + if (!(alarm & WAN_TE_BIT_LIU_ALARM_OC)){ + DEBUG_EVENT("%s: Open Circuit is detected!\n", + fe->name); } - if (lrsr & BIT_LRSR_SCS){ - if (!(fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC)){ - DEBUG_EVENT("%s: Short Circuit is detected!\n", - fe->name); - } - fe->liu_alarm |= WAN_TE_BIT_LIU_ALARM_SC; - }else{ - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ - DEBUG_EVENT("%s: Short Circuit is cleared!\n", - fe->name); - } - fe->liu_alarm &= ~WAN_TE_BIT_LIU_ALARM_SC; + alarm |= WAN_TE_BIT_LIU_ALARM_OC; + }else{ + if (alarm & WAN_TE_BIT_LIU_ALARM_OC){ + DEBUG_EVENT("%s: Open Circuit is cleared!\n", + fe->name); } - if (lrsr & BIT_LRSR_LOSS){ - if (!(fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_LOS)){ - DEBUG_EVENT("%s: Lost of Signal is detected!\n", - fe->name); - } - fe->liu_alarm |= WAN_TE_BIT_LIU_ALARM_LOS; - }else{ - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_LOS){ - DEBUG_EVENT("%s: Lost of Signal is cleared!\n", - fe->name); - } - fe->liu_alarm &= ~WAN_TE_BIT_LIU_ALARM_LOS; + alarm &= ~WAN_TE_BIT_LIU_ALARM_OC; + } + if (lrsr & BIT_LRSR_SCS){ + if (!(alarm & WAN_TE_BIT_LIU_ALARM_SC)){ + DEBUG_EVENT("%s: Short Circuit is detected!\n", + fe->name); } + alarm |= WAN_TE_BIT_LIU_ALARM_SC; + }else{ + if (alarm & WAN_TE_BIT_LIU_ALARM_SC){ + DEBUG_EVENT("%s: Short Circuit is cleared!\n", + fe->name); + } + alarm &= ~WAN_TE_BIT_LIU_ALARM_SC; + } + if (lrsr & BIT_LRSR_LOSS){ + if (!(alarm & WAN_TE_BIT_LIU_ALARM_LOS)){ + DEBUG_EVENT("%s: Lost of Signal is detected!\n", + fe->name); + } + alarm |= WAN_TE_BIT_LIU_ALARM_LOS; + }else{ + if (alarm & WAN_TE_BIT_LIU_ALARM_LOS){ + DEBUG_EVENT("%s: Lost of Signal is cleared!\n", + fe->name); + } + alarm &= ~WAN_TE_BIT_LIU_ALARM_LOS; + } + + return alarm; +} + +static unsigned int sdla_ds_te1_read_alarms(sdla_fe_t *fe, int action) +{ + unsigned int fr_alarm = fe->fe_alarm; + unsigned int alarm = fe->liu_alarm; + + if (IS_FE_ALARM_READ(action)){ + + fr_alarm = sdla_ds_te1_read_frame_alarms(fe); + alarm = sdla_ds_te1_read_liu_alarms(fe); } if (IS_FE_ALARM_PRINT(action)){ - sdla_ds_te1_print_alarms(fe, fe->fe_alarm); + sdla_ds_te1_print_alarms(fe, fr_alarm); } + if (IS_FE_ALARM_UPDATE(action)){ + fe->fe_alarm = fr_alarm; + fe->liu_alarm = alarm; + } return fe->fe_alarm; } +#define WAN_TE_CRIT_ALARM_TIMEOUT 30000 /* 30 sec */ +static int sdla_ds_te1_read_crit_alarms(sdla_fe_t *fe) +{ + + fe->liu_alarm = sdla_ds_te1_read_liu_alarms(fe); + if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + fe->te_param.crit_alarm_start = SYSTEM_TICKS; + }else{ + if((SYSTEM_TICKS - fe->te_param.crit_alarm_start) > ((WAN_TE_CRIT_ALARM_TIMEOUT * HZ)/1000)) { + /* The link was stable for 30 sec, let try to go back */ + return 0; + } + } + /* we are still in critical alarm state */ + return 1; +} + /* ******************************************************************************* ** sdla_ds_te1_set_alarms() @@ -2057,11 +2222,17 @@ sdla_ds_te1_intr_ctrl(sdla_fe_t *fe, int dummy, int type, int mode, unsigned int case WAN_TE_INTR_BASIC: if (mode == WAN_FE_INTR_ENABLE){ - WRITE_REG(REG_RIM1, - BIT_RIM1_RRAIC | BIT_RIM1_RRAID | - BIT_RIM1_RAISC | BIT_RIM1_RAISD | - BIT_RIM1_RLOSC | BIT_RIM1_RLOSD | - BIT_RIM1_RLOFC | BIT_RIM1_RLOFD); + unsigned char mask = 0x00; + + mask = BIT_RIM1_RAISC | BIT_RIM1_RAISD | + BIT_RIM1_RRAIC | BIT_RIM1_RRAID; + if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ + mask |= (BIT_RIM1_RLOFC | BIT_RIM1_RLOFD); + } +#if defined(FE_LOS_ENABLE) + mask |= (BIT_RIM1_RLOSC | BIT_RIM1_RLOSD); +#endif + WRITE_REG(REG_RIM1, mask); /*WRITE_REG(REG_RIM4, BIT_RIM4_TIMER);*/ WRITE_REG(REG_LSIMR, BIT_LSIMR_OCCIM | BIT_LSIMR_OCDIM | @@ -2147,17 +2318,19 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) DEBUG_TE1("%s: RX Latched Status Register 1 %02X\n", fe->name, rls1); - if (rls1 & (BIT_RLS1_RRAIC|BIT_RLS1_RRAID)){ - if (rrts1 & BIT_RRTS1_RRAI){ - fe->fe_alarm |= WAN_TE_BIT_RAI_ALARM; - DEBUG_EVENT("%s: RAI alarm is ON\n", - fe->name); - }else{ - fe->fe_alarm &= ~WAN_TE_BIT_RAI_ALARM; - DEBUG_EVENT("%s: RAI alarm is OFF\n", - fe->name); + //if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ + if (rls1 & (BIT_RLS1_RRAIC|BIT_RLS1_RRAID)){ + if (rrts1 & BIT_RRTS1_RRAI){ + fe->fe_alarm |= WAN_TE_BIT_RAI_ALARM; + DEBUG_EVENT("%s: RAI alarm is ON\n", + fe->name); + }else{ + fe->fe_alarm &= ~WAN_TE_BIT_RAI_ALARM; + DEBUG_EVENT("%s: RAI alarm is OFF\n", + fe->name); + } } - } + //} if (rls1 & (BIT_RLS1_RAISC|BIT_RLS1_RAISD)){ if (rrts1 & BIT_RRTS1_RAIS){ fe->fe_alarm |= WAN_TE_BIT_AIS_ALARM; @@ -2180,15 +2353,17 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) fe->name); } } - if (rls1 & (BIT_RLS1_RLOFC|BIT_RLS1_RLOFD)){ - if (rrts1 & BIT_RRTS1_RLOF){ - fe->fe_alarm |= WAN_TE_BIT_OOF_ALARM; - DEBUG_EVENT("%s: OOF alarm is ON\n", - fe->name); - }else{ - fe->fe_alarm &= ~WAN_TE_BIT_OOF_ALARM; - DEBUG_EVENT("%s: OOF alarm is OFF\n", - fe->name); + if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ + if (rls1 & (BIT_RLS1_RLOFC|BIT_RLS1_RLOFD)){ + if (rrts1 & BIT_RRTS1_RLOF){ + fe->fe_alarm |= WAN_TE_BIT_OOF_ALARM; + DEBUG_EVENT("%s: OOF alarm is ON\n", + fe->name); + }else{ + fe->fe_alarm &= ~WAN_TE_BIT_OOF_ALARM; + DEBUG_EVENT("%s: OOF alarm is OFF\n", + fe->name); + } } } WRITE_REG(REG_RLS1, rls1); @@ -2491,9 +2666,9 @@ static int sdla_ds_te1_liu_intr(sdla_fe_t *fe) static int sdla_ds_te1_check_intr(sdla_fe_t *fe) { - unsigned char framer_istatus; - unsigned char liu_istatus; - unsigned char bert_istatus; + unsigned char framer_istatus, framer_imask; + unsigned char liu_istatus, liu_imask; + unsigned char bert_istatus, bert_imask; WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); @@ -2502,6 +2677,10 @@ static int sdla_ds_te1_check_intr(sdla_fe_t *fe) liu_istatus = __READ_REG(REG_GLISR); bert_istatus = __READ_REG(REG_GBISR); + framer_imask = __READ_REG(REG_GFIMR); + liu_imask = __READ_REG(REG_GLIMR); + bert_imask = __READ_REG(REG_GBIMR); + //if (framer_istatus & (1 << WAN_FE_LINENO(fe))){ if (framer_istatus & (1 << WAN_DS_REGBITMAP(fe))){ DEBUG_ISR("%s: Interrupt for line %d (framer)\n", @@ -2509,17 +2688,27 @@ static int sdla_ds_te1_check_intr(sdla_fe_t *fe) return 1; } //if (liu_istatus & (1 << WAN_FE_LINENO(fe))){ - if (liu_istatus & (1 << WAN_DS_REGBITMAP(fe))){ - DEBUG_ISR("%s: Interrupt for line %d (liu)\n", + if ((framer_istatus & (1 << WAN_DS_REGBITMAP(fe))) && + (framer_imask & (1 << WAN_DS_REGBITMAP(fe)))) { + DEBUG_ISR("%s: Interrupt for line %d (FRAMER)\n", + fe->name, WAN_FE_LINENO(fe)); + return 1; + } + //if (liu_istatus & (1 << WAN_FE_LINENO(fe))){ + if ((liu_istatus & (1 << WAN_DS_REGBITMAP(fe))) && + (liu_imask & (1 << WAN_DS_REGBITMAP(fe)))) { + DEBUG_ISR("%s: Interrupt for line %d (LIU)\n", fe->name, WAN_FE_LINENO(fe)); return 1; } //if (bert_istatus & (1 << WAN_FE_LINENO(fe))){ - if (bert_istatus & (1 << WAN_DS_REGBITMAP(fe))){ - DEBUG_ISR("%s: Interrupt for line %d (bert)\n", + if ((bert_istatus & (1 << WAN_DS_REGBITMAP(fe))) && + (bert_imask & (1 << WAN_DS_REGBITMAP(fe)))) { + DEBUG_ISR("%s: Interrupt for line %d (BERT)\n", fe->name, WAN_FE_LINENO(fe)); return 1; } + DEBUG_ISR("%s: This interrupt not for this port %d\n", fe->name, WAN_FE_LINENO(fe)+1); @@ -2563,6 +2752,27 @@ static int sdla_ds_te1_intr(sdla_fe_t *fe) DEBUG_TE1("%s: FE Interrupt Alarms=0x%X\n", fe->name,fe->fe_alarm); +#if 1 + if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + sdla_fe_timer_event_t event; + /* AL: March 1, 2006: Mask global FE intr */ + sdla_ds_te1_intr_ctrl( + fe, 0, WAN_TE_INTR_BASIC, WAN_FE_INTR_MASK, 0x00); + /* Disable automatic update */ + sdla_ds_te1_intr_ctrl( + fe, 0, WAN_TE_INTR_PMON, WAN_FE_INTR_MASK, 0x00); + /* Start LINKDOWN poll */ + event.type = TE_LINKCRIT_TIMER; + event.delay = POLLING_TE1_TIMER*5; + sdla_ds_te1_add_event(fe, &event); + + //if (card->wandev.critical_event){ + // card->wandev.critical_event(card, 0); + //} + return 0; + } +#endif + sdla_ds_te1_set_status(fe, fe->fe_alarm); if (status != fe->fe_status){ if (fe->fe_status != FE_CONNECTED){ @@ -2570,7 +2780,7 @@ static int sdla_ds_te1_intr(sdla_fe_t *fe) /* AL: March 1, 2006: Mask global FE intr */ sdla_ds_te1_intr_ctrl( fe, 0, - WAN_TE_INTR_GLOBAL, + WAN_TE_INTR_BASIC, WAN_FE_INTR_MASK, 0x00); /* Disable automatic update */ @@ -2656,7 +2866,15 @@ static void sdla_ds_te1_timer(unsigned long pfe) */ static int sdla_ds_te1_add_timer(sdla_fe_t* fe, unsigned long delay) { - int err; + int err=0; + + if (wan_test_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical)){ + return 0; + } + + if (wan_test_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical)) { + return 0; + } err = wan_add_timer(&fe->timer, delay * HZ / 1000); if (err){ @@ -2707,18 +2925,39 @@ sdla_ds_te1_add_event(sdla_fe_t *fe, sdla_fe_timer_event_t *event) fe->name, __FUNCTION__,__LINE__); #endif wan_spin_lock_irq(&fe->lock,&smp_flags); + /* Set event from pending event map */ + if (wan_test_and_set_bit(event->type,(void*)&fe->event_map)){ + DEBUG_EVENT("%s: WARNING: Event type %d is already pending!\n", + fe->name, event->type); + wan_spin_unlock_irq(&fe->lock, &smp_flags); + wan_free(tevent); + return -EINVAL; + } if (WAN_LIST_EMPTY(&fe->event)){ WAN_LIST_INSERT_HEAD(&fe->event, tevent, next); }else{ sdla_fe_timer_event_t *tmp; + int cnt = 0; WAN_LIST_FOREACH(tmp, &fe->event, next){ if (!WAN_LIST_NEXT(tmp, next)) break; + cnt ++; } if (tmp == NULL){ DEBUG_EVENT("%s: Internal Error!!!\n", fe->name); + wan_clear_bit(event->type,(void*)&fe->event_map); wan_spin_unlock_irq(&fe->lock, &smp_flags); return -EINVAL; } + if (cnt > WAN_FE_MAX_QEVENT_LEN){ + DEBUG_EVENT("%s: ERROR: Too many events in event queue!\n", + fe->name); + DEBUG_EVENT("%s: ERROR: Dropping new event type %d!\n", + fe->name, event->type); + wan_clear_bit(event->type,(void*)&fe->event_map); + wan_spin_unlock_irq(&fe->lock, &smp_flags); + wan_free(tevent); + return -EINVAL; + } WAN_LIST_INSERT_AFTER(tmp, tevent, next); } wan_spin_unlock_irq(&fe->lock, &smp_flags); @@ -2765,13 +3004,32 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) } event = WAN_LIST_FIRST(&fe->event); WAN_LIST_REMOVE(event, next); + /* Clear event from pending event map */ + wan_clear_bit(event->type,(void*)&fe->event_map); wan_spin_unlock_irq(&fe->lock,&smp_flags); DEBUG_TE1("%s: TE1 Polling State=%s Event=%X!\n", fe->name, WAN_FE_STATUS_DECODE(fe), event->type); switch(event->type){ + case TE_LINKCRIT_TIMER: + if (!sdla_ds_te1_read_crit_alarms(fe)){ + event->type = TE_LINKDOWN_TIMER; + }else{ + event->type = TE_LINKCRIT_TIMER; + } + event->delay = POLLING_TE1_TIMER; + pending = 1; + break; + case TE_LINKDOWN_TIMER: - sdla_ds_te1_read_alarms(fe, WAN_FE_ALARM_READ); + sdla_ds_te1_read_alarms(fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); + if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + /* Short circuit detected, go to LINKCRIT state */ + event->type = TE_LINKCRIT_TIMER; + event->delay = POLLING_TE1_TIMER; + pending = 1; + break; + } sdla_ds_te1_pmon(fe, WAN_FE_PMON_UPDATE|WAN_FE_PMON_READ); sdla_ds_te1_set_status(fe, fe->fe_alarm); if (fe->fe_status == FE_CONNECTED){ @@ -2793,7 +3051,7 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) if (fe->fe_status == FE_CONNECTED){ /* Enable Basic Interrupt */ sdla_ds_te1_intr_ctrl( fe, 0, - WAN_TE_INTR_GLOBAL, + WAN_TE_INTR_BASIC, WAN_FE_INTR_ENABLE, 0x00); /* Enable automatic update pmon counters */ @@ -2884,7 +3142,7 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) /* Enable interrupts */ sdla_ds_te1_intr_ctrl(fe, 0, WAN_TE_INTR_BASIC, WAN_FE_INTR_ENABLE, 0x00); /* Enable manual update pmon counter */ - sdla_ds_te1_intr_ctrl(fe, 0, WAN_TE_INTR_PMON, WAN_FE_INTR_MASK, 0x00); + sdla_ds_te1_intr_ctrl(fe, 0, WAN_TE_INTR_PMON, WAN_FE_INTR_ENABLE, 0x00); event->type = TE_LINKDOWN_TIMER; event->delay = POLLING_TE1_TIMER; pending = 1; @@ -3206,6 +3464,7 @@ static int sdla_ds_te1_fr_plb(sdla_fe_t* fe, unsigned char mode) static int sdla_ds_te1_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) { + int err = 0; WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); @@ -3214,27 +3473,42 @@ sdla_ds_te1_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) WAN_TE1_LB_MODE_DECODE(mode), WAN_TE1_LB_TYPE_DECODE(type)); switch(type){ + case WAN_TE1_DDLB_MODE: case WAN_TE1_LIU_ALB_MODE: - sdla_ds_te1_liu_alb(fe, mode); + err = sdla_ds_te1_liu_alb(fe, mode); break; case WAN_TE1_LIU_LLB_MODE: - sdla_ds_te1_liu_llb(fe, mode); + err = sdla_ds_te1_liu_llb(fe, mode); break; + case WAN_TE1_LINELB_MODE: case WAN_TE1_LIU_RLB_MODE: - sdla_ds_te1_liu_rlb(fe, mode); + err = sdla_ds_te1_liu_rlb(fe, mode); break; case WAN_TE1_LIU_DLB_MODE: - sdla_ds_te1_liu_llb(fe, mode); - sdla_ds_te1_liu_rlb(fe, mode); + if (!sdla_ds_te1_liu_llb(fe, mode)){ + err = sdla_ds_te1_liu_rlb(fe, mode); + } break; case WAN_TE1_FR_FLB_MODE: - sdla_ds_te1_fr_flb(fe, mode); + err = sdla_ds_te1_fr_flb(fe, mode); break; + case WAN_TE1_PAYLB_MODE: case WAN_TE1_FR_PLB_MODE: - sdla_ds_te1_fr_plb(fe, mode); + err = sdla_ds_te1_fr_plb(fe, mode); break; case WAN_TE1_FR_RLB_MODE: - break; + default: + DEBUG_EVENT("%s: Unsupport loopback mode (%s)!\n", + fe->name, + WAN_TE1_LB_MODE_DECODE(mode)); + return -EINVAL; + } + if (!err){ + if (mode == WAN_TE1_ACTIVATE_LB){ + wan_set_bit(type, &fe->te_param.lb_mode); + }else{ + wan_clear_bit(type, &fe->te_param.lb_mode); + } } return 0; } @@ -3288,7 +3562,7 @@ static int sdla_ds_te1_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) DEBUG_EVENT("%s: Force to read Front-End alarms\n", fe->name); fe->fe_stats.alarms = - sdla_ds_te1_read_alarms(fe, WAN_FE_ALARM_READ); + sdla_ds_te1_read_alarms(fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); } sdla_ds_te1_rxlevel(fe); memcpy(&data[0], &fe->fe_stats, sizeof(sdla_fe_stats_t)); diff --git a/patches/kdrivers/src/net/sdla_aft_te1.c b/patches/kdrivers/src/net/sdla_aft_te1.c index 7320eb8..c0cf397 100644 --- a/patches/kdrivers/src/net/sdla_aft_te1.c +++ b/patches/kdrivers/src/net/sdla_aft_te1.c @@ -217,7 +217,8 @@ enum { AFT_FE_POLL, AFT_FE_TDM_RBS, AFT_FE_LED, - AFT_FE_EC_POLL + AFT_FE_EC_POLL, + AFT_FE_RESTART }; #define MAX_IP_ERRORS 10 @@ -472,6 +473,7 @@ static int aft_write_hdlc_frame(void *chan_ptr, netskb_t *skb); #endif static int aft_tdm_ring_rsync(sdla_t *card); static void aft_critical_shutdown(sdla_t *card); +static void aft_critical_event(void *arg, int type); /* API VoIP event */ #if defined(AFT_API_SUPPORT) @@ -759,6 +761,7 @@ int wp_aft_te1_init (sdla_t* card, wandev_conf_t* conf) conf->interface = IS_T1_CARD(card) ? WANOPT_V35 : WANOPT_RS232; + card->wandev.critical_event = aft_critical_event; if (card->wandev.comm_port == WANOPT_PRI){ conf->clocking = WANOPT_EXTERNAL; } @@ -5371,6 +5374,20 @@ static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr) int timeout=AFT_WDTCTRL_TIMEOUT; aft_wdt_reset(card); + + if (card->rsync_timeout){ + if (SYSTEM_TICKS - card->rsync_timeout > 3*HZ) { + card->rsync_timeout=0; + if (card->fe.fe_status == FE_CONNECTED) { + DEBUG_EVENT("%s: TDM IRQ Timeout \n", + card->devname); + wan_set_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } + } + aft_wdt_set(card,timeout); + return; + } for (i=0; iu.aft.num_of_time_slots;i++){ @@ -6599,6 +6616,7 @@ static void enable_data_error_intr(sdla_t *card) #endif card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + card->rsync_timeout=SYSTEM_TICKS; DEBUG_EVENT("%s: AFT Global TDM Intr\n", card->devname); @@ -8992,6 +9010,21 @@ static void aft_port_task (void * card_ptr, int arg) } } #endif + + + if (wan_test_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd)){ + wan_clear_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd); + if (card->fe.fe_status == FE_CONNECTED) { + DEBUG_EVENT("%s: TDM IRQ Restart\n", + card->devname); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + card->fe.fe_status = FE_DISCONNECTED; + handle_front_end_state(card); + card->fe.fe_status = FE_CONNECTED; + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + } + } } void __aft_fe_intr_ctrl(sdla_t *card, int status) @@ -10546,6 +10579,7 @@ static int aft_tdm_ring_rsync(sdla_t *card) card->u.aft.tdm_tx_dma_toggle = 0; } + card->rsync_timeout=0; DEBUG_EVENT("%s: Card TDM Rsync Rx=%i Tx=%i\n", card->devname, card->u.aft.tdm_rx_dma_toggle, @@ -10556,6 +10590,15 @@ static int aft_tdm_ring_rsync(sdla_t *card) return 0; } +static void aft_critical_event (void *arg, int type) +{ + sdla_t *card = (sdla_t*)arg; + DEBUG_EVENT("%s: Error: Card Critically Shutdown: Short Circuit Detected!\n", + card->devname); + aft_critical_shutdown(card); + return; +} + static void aft_critical_shutdown (sdla_t *card) { DEBUG_EVENT("%s: Error: Card Critically Shutdown!\n", @@ -10624,6 +10667,7 @@ static int aft_hwec_config (sdla_t *card, private_area_t *chan, wanif_conf_t *co } return err; + } diff --git a/patches/kdrivers/src/net/sdla_aft_te1.c~ b/patches/kdrivers/src/net/sdla_aft_te1.c~ new file mode 100644 index 0000000..6cc653d --- /dev/null +++ b/patches/kdrivers/src/net/sdla_aft_te1.c~ @@ -0,0 +1,10971 @@ +/***************************************************************************** +* sdla_aft_te1.c +* +* WANPIPE(tm) AFT TE1 Hardware Support +* +* Authors: Nenad Corbic +* +* Copyright: (c) 2003-2006 Sangoma Technologies Inc. +* +* 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. +* ============================================================================ +* Jan 07, 2003 Nenad Corbic Initial version. +* Oct 25, 2004 Nenad Corbic Support for QuadPort TE1 +*****************************************************************************/ + +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +# include +# include /* Socket Driver common area */ +# include +# include +# include +#else +# include +# include +# include +# include +# include +# include /* Socket Driver common area */ +# include +# include +# include +# include +# include +#endif + +#if defined(CONFIG_WANPIPE_HWEC) +# include +#endif + +#define INIT_FE_ONLY 0 + +#undef DEBUG_REG + +#if 1 +#define AFT_FUNC_DEBUG() +#else +#define AFT_FUNC_DEBUG() DEBUG_EVENT("%s:%d\n",__FUNCTION__,__LINE__) +#endif + + + +#if 0 +# define AFT_XTEST_UPDATE 1 +#else +# undef AFT_XTEST_UPDATE +#endif + + +#if 1 +# define AFT_SECURITY_CHECK 1 +#else +# undef AFT_SECURITY_CHECK +# warning "AFT_SECURITY_CHECK disabled" +#endif + +#if 1 +# define AFT_WDT_ENABLE 1 +#else +# warning "DISABLED WDT" +# undef AFT_WDT_ENABLE +#endif + +#if 0 +# define AFT_RX_FIFO_DEBUG 1 +# warning "AFT_RX_FIFO_DEBUG Flag used" +#else +# undef AFT_RX_FIFO_DEBUG +#endif + +#if 0 +# define AFT_TX_FIFO_DEBUG 1 +# warning "AFT_TX_FIFO_DEBUG Flag used" +#else +# undef AFT_TX_FIFO_DEBUG +#endif + +#if 0 +# define AFT_SINGLE_DMA_CHAIN 1 +# warning "AFT_SINGLE_DMA_CHAIN: SET" +#else +# undef AFT_SINGLE_DMA_CHAIN +#endif + +#if 1 +# define AFT_IFT_INTR_ENABLE 1 +#else +# warning "AFT_IFT_INTR_ENABLE NOT ENABLED" +# undef AFT_IFT_INTR_ENABLE +#endif + +#if 0 +# warning "IRQ INTR DEBUGGIN ON" +# define AFT_IRQ_DEBUG 1 +#else +# undef AFT_IRQ_DEBUG +#endif + +#if 0 +# warning "IRQ STAT DEBUGGIN ON" +# define AFT_IRQ_STAT_DEBUG 1 +#else +# undef AFT_IRQ_STAT_DEBUG +#endif + + +#if 0 +# define AFT_TDMV_BH_ENABLE 1 +# error "AFT_TDMV_BH_ENABLE flag used" +#else +# undef AFT_TDMV_BH_ENABLE +#endif + +#if 1 +# define AFT_TDMV_CHANNELIZATION 1 +#else +# undef AFT_TDMV_CHANNELIZATION +#endif + +#if 1 +# define AFT_CLOCK_SYNC 1 +#else +# undef AFT_CLOCK_SYNC +#endif + +#if defined(__LINUX__) +#define AFT_TDM_API_SUPPORT 1 +#else +#undef AFT_TDM_API_SUPPORT +#endif + +#if defined(__LINUX__) +#define AFT_API_SUPPORT 1 +#else +#undef AFT_API_SUPPORT +#endif + + +/* Trigger on Number of transactions + * 1= 1x8 byte transactions + * 2= 2x8 byte transactions + * 3= 3x8 byte transactions + * 4= 4x8 byte transactions + */ +#define AFT_TDMV_FIFO_LEVEL 1 +#define AFT_TDMV_CIRC_BUF 128 +#define AFT_TDMV_CIRC_BUF_LEN 4 +#define AFT_TDMV_BUF_MASK 0x1FF + +#define AFT_SS7_CTRL_LEN_MASK 0x0F +#define AFT_SS7_CTRL_TYPE_BIT 4 +#define AFT_SS7_CTRL_FORCE_BIT 5 + +#define AFT_MAX_CHIP_SECURITY_CNT 100 + +#define AFT_FE_FIX_FIRM_VER 100 + +aft_hw_dev_t aft_hwdev[MAX_AFT_HW_DEV]; + +enum { + TDM_RUNNING, + TDM_PENDING, +}; + +/****** Defines & Macros ****************************************************/ + +/* Private critical flags */ +enum { + POLL_CRIT = PRIV_CRIT, + CARD_DOWN, + TE_CFG, + CARD_HW_EC +}; + +enum { + LINK_DOWN, + DEVICE_DOWN +}; + +enum { + AFT_CHIP_CONFIGURED, + AFT_FRONT_END_UP, + AFT_TDM_GLOBAL_ISR, + AFT_TDM_RING_BUF, + AFT_TDM_FAST_ISR +}; + +enum { + TX_DMA_BUSY, + TX_HANDLER_BUSY, + TX_INTR_PENDING, + + RX_HANDLER_BUSY, + RX_DMA_BUSY, + RX_INTR_PENDING +}; + +enum { + AFT_FE_CFG_ERR, + AFT_FE_CFG, + AFT_FE_INTR, + AFT_FE_POLL, + AFT_FE_TDM_RBS, + AFT_FE_LED, + AFT_FE_EC_POLL, + AFT_FE_RESTART +}; + +#define MAX_IP_ERRORS 10 + +#define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" ) + + +#if 1 +# define TRUE_FIFO_SIZE 1 +#else +# undef TRUE_FIFO_SIZE +# define HARD_FIFO_CODE 0x1F +#endif + + +/* Remove HDLC Address + * 1=Remove Enabled + * 0=Remove Disabled + */ + +#if 0 +#define WANPIPE_CODEC_CONVERTER 1 +#else +#undef WANPIPE_CODEC_CONVERTER +#endif + +static int aft_rx_copyback=500; +/******Data Structures*****************************************************/ + +/* This structure is placed in the private data area of the device structure. + * The card structure used to occupy the private area but now the following + * structure will incorporate the card structure along with Protocol specific data + */ + + +/* Route Status options */ +#define NO_ROUTE 0x00 +#define ADD_ROUTE 0x01 +#define ROUTE_ADDED 0x02 +#define REMOVE_ROUTE 0x03 + +#define WP_WAIT 0 +#define WP_NO_WAIT 1 + +/* variable for keeping track of enabling/disabling FT1 monitor status */ +/* static int rCount; */ + +/* Function interface between WANPIPE layer and kernel */ +extern wan_iface_t wan_iface; + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +extern sdla_t* card_list; + +/**SECTOIN************************************************** + * + * Function Prototypes + * + ***********************************************************/ +int wp_aft_te1default_devcfg(sdla_t* card, wandev_conf_t* conf); +int wp_aft_te1default_ifcfg(sdla_t* card, wanif_conf_t* conf); + +/* WAN link driver entry points. These are called by the WAN router module. */ +static int update (wan_device_t* wandev); +static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf); +static int del_if(wan_device_t *wandev, netdevice_t *dev); + +/* Network device interface */ +#if defined(__LINUX__) +static int if_init (netdevice_t* dev); +#endif +static int if_open (netdevice_t* dev); +static int if_close (netdevice_t* dev); +static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); + +static struct net_device_stats* if_stats (netdevice_t* dev); + +#if defined(__LINUX__) +static int if_send (netskb_t* skb, netdevice_t* dev); +#else +static int if_send(netdevice_t*, netskb_t*, struct sockaddr*,struct rtentry*); +#endif + +static void handle_front_end_state(void* card_id); +static void enable_timer(void* card_id); +static void enable_ec_timer(void* card_id); +static void if_tx_timeout (netdevice_t *dev); + +/* Miscellaneous Functions */ +static void port_set_state (sdla_t *card, int); + +static void disable_comm (sdla_t *card); + +/* Interrupt handlers */ +static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card); +static void wp_aft_dma_per_port_isr(sdla_t *card); +static void wp_aft_tdmv_per_port_isr(sdla_t *card); +static void wp_aft_fifo_per_port_isr(sdla_t *card); +static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr); + +/* Bottom half handlers */ +#if defined(__LINUX__) +static void wp_bh (unsigned long); +static void wp_tdm_bh (unsigned long); +#else +static void wp_bh (void*,int); +static void wp_tdm_bh (void*,int); +#endif + +/* Miscellaneous functions */ +static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, + private_area_t*, + int local_dev); + +static int aft_global_chip_configuration(sdla_t *card, wandev_conf_t* conf); +static int aft_global_chip_disable(sdla_t *card); + +static int aft_chip_configure(sdla_t *card, wandev_conf_t* conf); +static int aft_chip_unconfigure(sdla_t *card); +static int aft_dev_configure(sdla_t *card, private_area_t *chan, wanif_conf_t* conf); +static void aft_dev_unconfigure(sdla_t *card, private_area_t *chan); + +static int aft_dma_rx(sdla_t *card, private_area_t *chan); +static void aft_dev_enable(sdla_t *card, private_area_t *chan); +static void aft_dev_close(sdla_t *card, private_area_t *chan); +static void aft_dev_open(sdla_t *card, private_area_t *gchan); +static void aft_dma_tx_complete (sdla_t *card, private_area_t *chan,int wdt, int reset); + +static int aft_dma_rx_complete(sdla_t *card, private_area_t *chan, int reset); +static int aft_init_rx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char); +static int aft_init_tx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char); +static void aft_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_t *skb); +static void aft_rx_post_complete (sdla_t *card, private_area_t *chan, + netskb_t *skb, + netskb_t **new_skb, + unsigned char *pkt_error); +static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan); +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) +static int aft_voice_span_rx_tx(sdla_t *card, int rotate); +#endif + +static void aft_channel_txdma_ctrl(sdla_t *card, private_area_t *chan, int on); +static void aft_channel_rxdma_ctrl(sdla_t *card, private_area_t *chan, int on); +static void aft_channel_txintr_ctrl(sdla_t *card, private_area_t *chan, int on); +static void aft_channel_rxintr_ctrl(sdla_t *card, private_area_t *chan, int on); + +static int aft_read_security(sdla_t *card); +static int aft_front_end_mismatch_check(sdla_t * card); +static int aft_tslot_sync_ctrl(sdla_t *card, private_area_t *chan, int mode); + +#if defined(__LINUX__) +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +static void aft_port_task (void * card_ptr); +# else +static void aft_port_task (struct work_struct *work); +# endif +#else +static void aft_port_task (void * card_ptr, int arg); +#endif + +#if defined(__LINUX__) +static void aft_rtp_config(sdla_t *card); +static void aft_rtp_unconfig(sdla_t *card); +#if 0 +static void aft_rtp_tap(sdla_t *card, private_area_t *chan, u8* rx, u8* tx, u32 len); +#endif +#endif + +static int aft_devel_ioctl(sdla_t *card,struct ifreq *ifr); +static int aft_write_bios(sdla_t *card, wan_cmd_api_t *api_cmd); +static int aft_write(sdla_t *card, wan_cmd_api_t *api_cmd); +static int aft_read(sdla_t *card, wan_cmd_api_t *api_cmd); +static int aft_fe_write(sdla_t *card, wan_cmd_api_t *api_cmd); +static int aft_fe_read(sdla_t *card, wan_cmd_api_t *api_cmd); + +static void front_end_interrupt(sdla_t *card, unsigned long reg, int lock); +static void enable_data_error_intr(sdla_t *card); +static void disable_data_error_intr(sdla_t *card, unsigned char); + +static void aft_tx_fifo_under_recover (sdla_t *card, private_area_t *chan); +static void aft_rx_fifo_over_recover(sdla_t *card, private_area_t *chan); + +static int set_chan_state(sdla_t* card, netdevice_t* dev, int state); + +static int update_comms_stats(sdla_t* card); + +static int protocol_init (sdla_t*card,netdevice_t *dev, + private_area_t *chan, wanif_conf_t* conf); +static int protocol_stop (sdla_t *card, netdevice_t *dev); +static int protocol_shutdown (sdla_t *card, netdevice_t *dev); +static void protocol_recv(sdla_t *card, private_area_t *chan, netskb_t *skb); + +static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num, int irq); +static int aft_init_requeue_free_skb(private_area_t *chan, netskb_t *skb); + + +static int aft_dma_tx (sdla_t *card,private_area_t *chan); +static void aft_tx_dma_chain_handler(unsigned long data, int wdt, int reset); +static void aft_tx_dma_voice_handler(unsigned long data, int wdt, int reset); +static void aft_tx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *); +static void aft_rx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *); +static void aft_index_tx_rx_dma_chains(private_area_t *chan); +static void aft_init_tx_rx_dma_descr(private_area_t *chan); +static void aft_free_rx_complete_list(private_area_t *chan); +static void aft_rx_cur_go_test(private_area_t *chan); +static void aft_free_rx_descriptors(private_area_t *chan); +static void aft_reset_rx_chain_cnt(private_area_t *chan); +static void aft_reset_tx_chain_cnt(private_area_t *chan); +static void aft_free_tx_descriptors(private_area_t *chan); + + +static int aft_realign_skb_pkt(private_area_t *chan, netskb_t *skb); + +static void aft_data_mux_cfg(sdla_t *card); +static void aft_data_mux_get_cfg(sdla_t *card); + +static int aft_ss7_tx_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb); + +static int aft_tdmv_init(sdla_t *card, wandev_conf_t *conf); +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) +static int aft_tdmv_free(sdla_t *card); +#endif +static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf); +static int aft_tdmv_if_free(sdla_t *card, private_area_t *chan); + +static int digital_loop_test(sdla_t* card,wan_udp_pkt_t* wan_udp_pkt); + +#if 0 +static void wp_tdmv_api_chan_rx_tx(sdla_t *card, + private_area_t *chan, + unsigned char *rxdata, unsigned char *tx_data); +static void wp_tdmv_api_rx_tx (sdla_t *card, private_area_t *chan); +#endif + +static int aft_fifo_intr_ctrl(sdla_t *card, int ctrl); +static int aft_tdm_intr_ctrl(sdla_t *card, int ctrl); + +#if defined(__LINUX__) +static void aft_set_ss7_force_rx(sdla_t *card, private_area_t *chan); +#endif +static void aft_clear_ss7_force_rx(sdla_t *card, private_area_t *chan); + +#if defined(AFT_API_SUPPORT) || defined(AFT_TDM_API_SUPPORT) +static int aft_event_ctrl(void *chan_ptr, wan_event_ctrl_t *ctrl); +#endif + +#ifdef AFT_TDM_API_SUPPORT +static int aft_read_rbs_bits(void *chan_ptr, u32 ch, u8 *rbs_bits); +static int aft_write_rbs_bits(void *chan_ptr, u32 ch, u8 rbs_bits); +static int aft_write_hdlc_frame(void *chan_ptr, netskb_t *skb); +#endif +static int aft_tdm_ring_rsync(sdla_t *card); +static void aft_critical_shutdown(sdla_t *card); +static void aft_critical_event(void *arg, int type); + +/* API VoIP event */ +#if defined(AFT_API_SUPPORT) +static int wan_aft_api_ioctl(sdla_t *card, private_area_t *chan, char *user_data); +static void wan_aft_api_dtmf (void* card_id, wan_event_t *event); +static void wan_aft_api_hook (void* card_id, wan_event_t *event); +static void wan_aft_api_ringtrip (void* card_id, wan_event_t *event); +static void wan_aft_api_ringdetect (void* card_id, wan_event_t *event); +#endif + +#if 0 +static void aft_list_descriptors(private_area_t *chan); +#endif +#if 0 +static void aft_list_dma_chain_regs(sdla_t *card); +#endif + +#if 0 +static void aft_list_tx_descriptors(private_area_t *chan); +#endif +#if 0 +static void aft_display_chain_history(private_area_t *chan); +static void aft_chain_history(private_area_t *chan,u8 end, u8 cur, u8 begin, u8 loc); +#endif + + +/* TE1 Control registers */ +#if 0 +static WRITE_FRONT_END_REG_T write_front_end_reg; +static READ_FRONT_END_REG_T read_front_end_reg; +#endif + +unsigned char aft_read_cpld(sdla_t *card, unsigned short cpld_off); +int aft_write_cpld(void *pcard, unsigned short off,unsigned char data); + +/* Procfs functions */ +static int wan_aft_get_info(void* pcard, struct seq_file* m, int* stop_cnt); + +static int wan_aft_init (sdla_t *card, wandev_conf_t* conf); + + +static unsigned char aft_write_ec (void*, unsigned short, unsigned char); +static unsigned char aft_read_ec (void*, unsigned short); + +static int aft_hwec_config(sdla_t *card, private_area_t *chan, wanif_conf_t *conf, int ctrl); +static int aft_find_master_if_and_dchan(sdla_t *card, int *master_if,u32 active_ch); + + +/**SECTION********************************************************* + * + * Public Functions + * + ******************************************************************/ + +int wp_aft_te1default_devcfg(sdla_t* card, wandev_conf_t* conf) +{ + conf->config_id = WANCONFIG_AFT_TE1; + conf->u.aft.dma_per_ch = MAX_RX_BUF; + conf->u.aft.mru = 1500; + return 0; +} + +int wp_aft_te1default_ifcfg(sdla_t* card, wanif_conf_t* conf) +{ + conf->protocol = WANCONFIG_HDLC; + memcpy(conf->usedby, "WANPIPE", 7); + conf->if_down = 0; + conf->ignore_dcd = WANOPT_NO; + conf->ignore_cts = WANOPT_NO; + conf->hdlc_streaming = WANOPT_NO; + conf->mc = 0; + conf->gateway = 0; + conf->active_ch = ENABLE_ALL_CHANNELS; + + return 0; +} + +#if 0 +static void aft_delay(int sec) +{ +#if 1 + unsigned long timeout=SYSTEM_TICKS; + while ((SYSTEM_TICKS-timeout)<(sec*HZ)){ + schedule(); + } +#endif +} +#endif + + +int aft_global_hw_device_init(void) +{ + memset(aft_hwdev,0,sizeof(aft_hwdev)); + + aft_hwdev[WANOPT_AFT104].init = 1; + aft_hwdev[WANOPT_AFT104].aft_global_chip_config = a104_global_chip_config; + aft_hwdev[WANOPT_AFT104].aft_global_chip_unconfig = a104_global_chip_unconfig; + aft_hwdev[WANOPT_AFT104].aft_chip_config = a104_chip_config; + aft_hwdev[WANOPT_AFT104].aft_chip_unconfig = a104_chip_unconfig; + aft_hwdev[WANOPT_AFT104].aft_chan_config = a104_chan_dev_config; + aft_hwdev[WANOPT_AFT104].aft_chan_unconfig = a104_chan_dev_unconfig; + aft_hwdev[WANOPT_AFT104].aft_led_ctrl = a104_led_ctrl; + aft_hwdev[WANOPT_AFT104].aft_test_sync = a104_test_sync; + aft_hwdev[WANOPT_AFT104].aft_read_cpld = aft_te1_read_cpld; + aft_hwdev[WANOPT_AFT104].aft_write_cpld = aft_te1_write_cpld; + aft_hwdev[WANOPT_AFT104].aft_fifo_adjust = a104_fifo_adjust; + aft_hwdev[WANOPT_AFT104].aft_check_ec_security = a104_check_ec_security; + + aft_hwdev[WANOPT_AFT_ANALOG].init = 1; + aft_hwdev[WANOPT_AFT_ANALOG].aft_global_chip_config = aft_analog_global_chip_config; + aft_hwdev[WANOPT_AFT_ANALOG].aft_global_chip_unconfig = aft_analog_global_chip_unconfig; + aft_hwdev[WANOPT_AFT_ANALOG].aft_chip_config = aft_analog_chip_config; + aft_hwdev[WANOPT_AFT_ANALOG].aft_chip_unconfig = aft_analog_chip_unconfig; + aft_hwdev[WANOPT_AFT_ANALOG].aft_chan_config = aft_analog_chan_dev_config; + aft_hwdev[WANOPT_AFT_ANALOG].aft_chan_unconfig = aft_analog_chan_dev_unconfig; + aft_hwdev[WANOPT_AFT_ANALOG].aft_led_ctrl = aft_analog_led_ctrl; + aft_hwdev[WANOPT_AFT_ANALOG].aft_test_sync = aft_analog_test_sync; + aft_hwdev[WANOPT_AFT_ANALOG].aft_read_cpld = aft_analog_read_cpld; + aft_hwdev[WANOPT_AFT_ANALOG].aft_write_cpld = aft_analog_write_cpld; + aft_hwdev[WANOPT_AFT_ANALOG].aft_fifo_adjust = aft_analog_fifo_adjust; + aft_hwdev[WANOPT_AFT_ANALOG].aft_check_ec_security = a200_check_ec_security; + + aft_hwdev[WANOPT_AFT_56K].init = 1; + aft_hwdev[WANOPT_AFT_56K].aft_global_chip_config = a104_global_chip_config; + aft_hwdev[WANOPT_AFT_56K].aft_global_chip_unconfig = a104_global_chip_unconfig; + aft_hwdev[WANOPT_AFT_56K].aft_chip_config = a104_chip_config; + aft_hwdev[WANOPT_AFT_56K].aft_chip_unconfig = a104_chip_unconfig; + aft_hwdev[WANOPT_AFT_56K].aft_chan_config = a104_chan_dev_config; + aft_hwdev[WANOPT_AFT_56K].aft_chan_unconfig = a104_chan_dev_unconfig; + aft_hwdev[WANOPT_AFT_56K].aft_led_ctrl = a104_led_ctrl; + aft_hwdev[WANOPT_AFT_56K].aft_test_sync = a104_test_sync; + aft_hwdev[WANOPT_AFT_56K].aft_read_cpld = aft_56k_read_cpld; + aft_hwdev[WANOPT_AFT_56K].aft_write_cpld = aft_56k_write_cpld; + aft_hwdev[WANOPT_AFT_56K].aft_fifo_adjust = a104_fifo_adjust; + aft_hwdev[WANOPT_AFT_56K].aft_check_ec_security = a104_check_ec_security; + + return 0; +} + + +/*============================================================================ + * wp_aft_te1_init - Cisco HDLC protocol initialization routine. + * + * @card: Wanpipe card pointer + * @conf: User hardware/firmware/general protocol configuration + * pointer. + * + * This routine is called by the main WANPIPE module + * during setup: ROUTER_SETUP ioctl(). + * + * At this point adapter is completely initialized + * and firmware is running. + * o read firmware version (to make sure it's alive) + * o configure adapter + * o initialize protocol-specific fields of the adapter data space. + * + * Return: 0 o.k. + * < 0 failure. + */ + +int wp_aft_analog_init (sdla_t *card, wandev_conf_t* conf) +{ + /* Verify configuration ID */ + if (card->wandev.config_id != WANCONFIG_AFT_ANALOG) { + DEBUG_EVENT( "%s: invalid configuration ID %u!\n", + card->devname, card->wandev.config_id); + return -EINVAL; + } + + ASSERT_AFT_HWDEV(card->wandev.card_type); + + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); + card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); + if (card->u.aft.firm_ver < AFT_MIN_ANALOG_FRMW_VER){ + DEBUG_EVENT( "%s: Invalid/Obselete AFT ANALOG firmware version %X (not >= %X)!\n", + card->devname, card->u.aft.firm_ver,AFT_MIN_ANALOG_FRMW_VER); + DEBUG_EVENT( "%s Refer to /usr/share/doc/wanpipe/README.aft_firm_update\n", + card->devname); + DEBUG_EVENT( "%s: Please contact Sangoma Technologies for more info.\n", + card->devname); + return -EINVAL; + } + + if (conf == NULL){ + DEBUG_EVENT("%s: Bad configuration structre!\n", + card->devname); + return -EINVAL; + } + + /* Make special hardware initialization for Analog board */ + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); + wp_remora_iface_init(&card->wandev.fe_iface); + card->fe.name = card->devname; + card->fe.card = card; + card->fe.write_fe_reg = aft_analog_write_fe; + card->fe.read_fe_reg = aft_analog_read_fe; + card->fe.__read_fe_reg = __aft_analog_read_fe; + + card->wandev.fe_enable_timer = enable_timer; + card->wandev.ec_enable_timer = enable_ec_timer; + card->wandev.te_link_state = handle_front_end_state; + + if (card->wandev.comm_port == WANOPT_PRI){ + conf->clocking = WANOPT_EXTERNAL; + } + + card->wandev.comm_port=card->fe.fe_cfg.line_no; + if (card->wandev.comm_port != 0){ + DEBUG_EVENT("%s: Error: Invalid port selected %d (Port 1)\n", + card->devname,card->wandev.comm_port); + return -EINVAL; + } + + card->u.aft.num_of_time_slots=MAX_REMORA_MODULES; + + return wan_aft_init(card,conf); + +} + + +int wp_aft_te1_init (sdla_t* card, wandev_conf_t* conf) +{ + + AFT_FUNC_DEBUG(); + + wan_set_bit(CARD_DOWN,&card->wandev.critical); + + /* Verify configuration ID */ + if (card->wandev.config_id != WANCONFIG_AFT_TE1) { + DEBUG_EVENT( "%s: invalid configuration ID %u!\n", + card->devname, card->wandev.config_id); + return -EINVAL; + } + + + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); + card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); + + if (card->u.aft.firm_ver < AFT_MIN_FRMW_VER){ + DEBUG_EVENT( "%s: Invalid/Obselete AFT firmware version %X (not >= %X)!\n", + card->devname, card->u.aft.firm_ver,AFT_MIN_FRMW_VER); + DEBUG_EVENT( "%s Refer to /usr/share/doc/wanpipe/README.aft_firm_update\n", + card->devname); + DEBUG_EVENT( "%s: Please contact Sangoma Technologies for more info.\n", + card->devname); + return -EINVAL; + } + + ASSERT_AFT_HWDEV(card->wandev.card_type); + + if (conf == NULL){ + DEBUG_EVENT("%s: Bad configuration structre!\n", + card->devname); + return -EINVAL; + } + +#if defined(WAN_DEBUG_MEM) + DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); +#endif + + /* TE1 Make special hardware initialization for T1/E1 board */ + if (IS_TE1_MEDIA(&conf->fe_cfg)){ + int max_ports = 4; + + if (conf->fe_cfg.cfg.te_cfg.active_ch == 0){ + conf->fe_cfg.cfg.te_cfg.active_ch = -1; + } + + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); + if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID) { + max_ports = 8; + sdla_ds_te1_iface_init(&card->wandev.fe_iface); + }else{ + sdla_te_iface_init(&card->wandev.fe_iface); + } + card->fe.name = card->devname; + card->fe.card = card; + card->fe.write_fe_reg = a104_write_fe; + card->fe.read_fe_reg = a104_read_fe; + card->fe.__read_fe_reg = __a104_read_fe; + + card->wandev.fe_enable_timer = enable_timer; + card->wandev.ec_enable_timer = enable_ec_timer; + card->wandev.te_link_state = handle_front_end_state; + conf->interface = + IS_T1_CARD(card) ? WANOPT_V35 : WANOPT_RS232; + + card->wandev.critical_event = aft_critical_event; + if (card->wandev.comm_port == WANOPT_PRI){ + conf->clocking = WANOPT_EXTERNAL; + } + + card->wandev.comm_port=card->fe.fe_cfg.line_no; +#if 0 +/* ALEX: This will check during t1/e1 configuration */ + if (card->wandev.comm_port < 0 || card->wandev.comm_port > max_ports-1){ + DEBUG_EVENT("%s: Error: Invalid port selected %d (Min=1 Max=%d)\n", + card->devname,card->wandev.comm_port, max_ports); + return -EINVAL; + } +#endif + + if (IS_T1_CARD(card)){ + card->u.aft.num_of_time_slots=NUM_OF_T1_CHANNELS; + }else{ + card->u.aft.num_of_time_slots=NUM_OF_E1_CHANNELS; + } + + }else{ + DEBUG_EVENT("%s: Invalid Front-End media type!!\n", + card->devname); + return -EINVAL; + } + + return wan_aft_init(card,conf); + +} + +int wp_aft_56k_init (sdla_t* card, wandev_conf_t* conf) +{ + + AFT_FUNC_DEBUG(); + + wan_set_bit(CARD_DOWN,&card->wandev.critical); + + /* Verify configuration ID */ + if (card->wandev.config_id != WANCONFIG_AFT_56K) { + DEBUG_EVENT( "%s: invalid configuration ID %u!\n", + card->devname, card->wandev.config_id); + return -EINVAL; + } + + + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); + card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); +#if 0 + if (card->u.aft.firm_ver < AFT_56K_MIN_FRMW_VER){ + DEBUG_EVENT( "%s: Invalid/Obselete AFT firmware version %X (not >= %X)!\n", + card->devname, card->u.aft.firm_ver,AFT_56K_MIN_FRMW_VER); + DEBUG_EVENT( "%s Refer to /usr/share/doc/wanpipe/README.aft_firm_update\n", + card->devname); + DEBUG_EVENT( "%s: Please contact Sangoma Technologies for more info.\n", + card->devname); + return -EINVAL; + } +#endif + ASSERT_AFT_HWDEV(card->wandev.card_type); + + if (conf == NULL){ + DEBUG_EVENT("%s: Bad configuration structre!\n", + card->devname); + return -EINVAL; + } + +#if defined(WAN_DEBUG_MEM) + DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); +#endif + + if (IS_56K_MEDIA(&conf->fe_cfg)){ + + conf->fe_cfg.cfg.te_cfg.active_ch = 1; + + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); + + DEBUG_56K("card->u.aft.firm_id: 0x%X\n", card->u.aft.firm_id); +/* + if(card->u.aft.firm_id != AFT_56K_FE_CORE_ID){ + DEBUG_EVENT("%s: Invalid (56K) Firmware ID: 0x%X!\n", + card->devname, card->u.aft.firm_id); + return -EINVAL; + } +*/ + sdla_56k_iface_init(&card->wandev.fe_iface); + + card->fe.name = card->devname; + card->fe.card = card; +#if 1 + card->fe.write_fe_reg = a56k_write_fe; + card->fe.read_fe_reg = a56k_read_fe; + card->fe.__read_fe_reg = __a56k_read_fe; +#else + card->fe.write_fe_reg = a104_write_fe; + card->fe.read_fe_reg = a104_read_fe; + card->fe.__read_fe_reg = __a104_read_fe; +#endif + card->wandev.fe_enable_timer = enable_timer; + card->wandev.ec_enable_timer = enable_ec_timer; + card->wandev.te_link_state = handle_front_end_state; + + card->wandev.comm_port=1; + + card->u.aft.num_of_time_slots=1; + + }else{ + DEBUG_EVENT("%s: Invalid Front-End media type!!\n", + card->devname); + return -EINVAL; + } + + return wan_aft_init(card,conf); + +} + +static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) +{ + int err; + int used_cnt; + + /* Obtain hardware configuration parameters */ + card->wandev.clocking = conf->clocking; + card->wandev.ignore_front_end_status = conf->ignore_front_end_status; + card->wandev.ttl = conf->ttl; + card->wandev.interface = conf->interface; + card->wandev.comm_port = conf->comm_port; + card->wandev.udp_port = conf->udp_port; + card->wandev.new_if_cnt = 0; + wan_atomic_set(&card->wandev.if_cnt,0); + card->u.aft.chip_security_cnt=0; + + memcpy(&card->u.aft.cfg,&conf->u.aft,sizeof(wan_xilinx_conf_t)); + memset(card->u.aft.dev_to_ch_map,0,sizeof(card->u.aft.dev_to_ch_map)); + memcpy(&card->tdmv_conf,&conf->tdmv_conf,sizeof(wan_tdmv_conf_t)); + memcpy(&card->hwec_conf,&conf->hwec_conf,sizeof(wan_hwec_conf_t)); + + card->u.aft.cfg.dma_per_ch = MAX_RX_BUF; + card->u.aft.tdmv_api_rx = NULL; + card->u.aft.tdmv_api_tx = NULL; + card->u.aft.tdmv_dchan=0; + wan_skb_queue_init(&card->u.aft.tdmv_api_tx_list); + + if (card->wandev.ignore_front_end_status == WANOPT_NO){ + DEBUG_EVENT( + "%s: Enabling front end link monitor\n", + card->devname); + }else{ + DEBUG_EVENT( + "%s: Disabling front end link monitor\n", + card->devname); + } + + AFT_FUNC_DEBUG(); + + /* WARNING: After this point the init function + * must return with 0. The following bind + * functions will cause problems if structures + * below are not initialized */ + + card->wandev.update = &update; + card->wandev.new_if = &new_if; + card->wandev.del_if = &del_if; + card->disable_comm = NULL; + + +#ifdef WANPIPE_ENABLE_PROC_FILE_HOOKS + /* Proc fs functions hooks */ + card->wandev.get_config_info = &get_config_info; + card->wandev.get_status_info = &get_status_info; + card->wandev.get_dev_config_info= &get_dev_config_info; + card->wandev.get_if_info = &get_if_info; + card->wandev.set_dev_config = &set_dev_config; + card->wandev.set_if_info = &set_if_info; +#endif + card->wandev.get_info = &wan_aft_get_info; + + /* Setup Port Bps */ + if(card->wandev.clocking) { + card->wandev.bps = conf->bps; + }else{ + card->wandev.bps = 0; + } + + /* For Primary Port 0 */ +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + card->wandev.mtu = conf->mtu; + card->wan_tdmv.sc = NULL; +#else + card->wandev.mtu=conf->mtu; + if (card->wandev.mtu > MAX_WP_PRI_MTU || + card->wandev.mtu < MIN_WP_PRI_MTU){ + DEBUG_EVENT("%s: Error Invalid Global MTU %d (Min=%d, Max=%d)\n", + card->devname,card->wandev.mtu, + MIN_WP_PRI_MTU,MAX_WP_PRI_MTU); + + return -EINVAL; + } +#endif + + + if (!card->u.aft.cfg.mru){ + card->u.aft.cfg.mru = card->wandev.mtu; + } + + + + if (card->u.aft.cfg.mru > MAX_WP_PRI_MTU || + card->u.aft.cfg.mru < MIN_WP_PRI_MTU){ + DEBUG_EVENT("%s: Error Invalid Global MRU %d (Min=%d, Max=%d)\n", + card->devname,card->u.aft.cfg.mru, + MIN_WP_PRI_MTU,MAX_WP_PRI_MTU); + + return -EINVAL; + } + + card->hw_iface.getcfg(card->hw, SDLA_BASEADDR, &card->u.aft.bar); + card->hw_iface.getcfg(card->hw, SDLA_MEMBASE, &card->u.aft.bar_virt); + + port_set_state(card,WAN_CONNECTING); + + AFT_FUNC_DEBUG(); + + WAN_TASKQ_INIT((&card->u.aft.port_task),0,aft_port_task,card); + + card->u.aft.chip_cfg_status=0; + card->hw_iface.getcfg(card->hw, SDLA_USEDCNT, &used_cnt); + + wan_clear_bit(CARD_DOWN,&card->wandev.critical); + + __sdla_push_ptr_isr_array(card->hw,card,card->wandev.comm_port); + + card->isr = &wp_aft_global_isr; + + if (used_cnt==1){ + DEBUG_EVENT("%s: Global Chip Configuration: used=%d\n", + card->devname,used_cnt); + + err=aft_global_chip_configuration(card, conf); + if (err){ + aft_global_chip_disable(card); + return err; + } + + aft_data_mux_cfg(card); + + }else{ + + aft_data_mux_get_cfg(card); + + err=aft_front_end_mismatch_check(card); + if (err){ + return err; + } + + DEBUG_EVENT("%s: Global Chip Configuration skiped: used=%d\n", + card->devname,used_cnt); + } + card->wandev.ec_intmask=SYSTEM_TICKS; + + aft_read_security(card); + + err=aft_chip_configure(card,conf); + if (err){ + AFT_FUNC_DEBUG(); + + aft_chip_unconfigure(card); + if (used_cnt==1){ + aft_global_chip_disable(card); + } + return err; + } + wan_set_bit(AFT_CHIP_CONFIGURED,&card->u.aft.chip_cfg_status); + + if (wan_test_bit(AFT_FRONT_END_UP,&card->u.aft.chip_cfg_status)){ + wan_smp_flag_t smp_flags; + DEBUG_TEST("%s: Front end up, retrying enable front end!\n", + card->devname); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + + wan_clear_bit(AFT_FRONT_END_UP,&card->u.aft.chip_cfg_status); + } + + AFT_FUNC_DEBUG(); + + aft_read_security(card); + + + DEBUG_EVENT("%s: Configuring Device :%s FrmVr=%02X\n", + card->devname,card->devname,card->u.aft.firm_ver); + DEBUG_EVENT("%s: Global MTU = %d\n", + card->devname, + card->wandev.mtu); + DEBUG_EVENT("%s: Global MRU = %d\n", + card->devname, + card->u.aft.cfg.mru); + DEBUG_EVENT("%s: Data Mux Map = 0x%08X\n", + card->devname, + card->u.aft.cfg.data_mux_map); + DEBUG_EVENT("%s: Rx CRC Bytes = %i\n", + card->devname, + card->u.aft.cfg.rx_crc_bytes); + + wan_clear_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status); + wan_clear_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status); + + if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID) { + if ((card->adptr_type == A108_ADPTR_8TE1 && + card->u.aft.firm_ver >= 0x27) || + (card->adptr_type == A104_ADPTR_4TE1 && + card->u.aft.firm_ver >= 0x26) || + (card->adptr_type == A101_ADPTR_2TE1 && + card->u.aft.firm_ver >= 0x26) || + (card->adptr_type == A101_ADPTR_1TE1 && + card->u.aft.firm_ver >= 0x26)) { + wan_set_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status); + wan_set_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status); + } + } else { + if ((card->adptr_type == A104_ADPTR_4TE1 && + card->adptr_subtype == AFT_SUBTYPE_SHARK && + card->u.aft.firm_ver >= 0x23)) { + wan_set_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status); + wan_set_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status); + } + } + + DEBUG_EVENT("%s: Global TDM Int = %s\n", + card->devname, + wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status) ? + "Enabled" : "Disabled"); + + DEBUG_EVENT("%s: Global TDM Ring= %s\n", + card->devname, + wan_test_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status) ? + "Enabled" : "Disabled"); + + if (card->wandev.ec_dev){ + card->u.aft.tdmv_hw_dtmf = conf->tdmv_conf.hw_dtmf; + }else{ + card->u.aft.tdmv_hw_dtmf = WANOPT_NO; + } + DEBUG_EVENT("%s: Global TDM HW DTMF = %s\n", + card->devname, + (card->u.aft.tdmv_hw_dtmf == WANOPT_YES) ? + "Enabled" : "Disabled"); + + err=aft_tdmv_init(card,conf); + if (err){ + disable_comm(card); + return err; + } + + card->disable_comm = &disable_comm; + + aft_rtp_config(card); + + + card->wandev.read_ec = aft_read_ec; + card->wandev.write_ec = aft_write_ec; + return 0; + +} + + + + +/**SECTION************************************************************** + * + * WANPIPE Device Driver Entry Points + * + * *********************************************************************/ + + + +/*============================================================================ + * update - Update wanpipe device status & statistics + * + * @wandev: Wanpipe device pointer + * + * This procedure is called when updating the PROC file system. + * It returns various communications statistics. + * + * cat /proc/net/wanrouter/wanpipe# (where #=1,2,3...) + * + * These statistics are accumulated from 3 + * different locations: + * 1) The 'if_stats' recorded for the device. + * 2) Communication error statistics on the adapter. + * 3) Operational statistics on the adapter. + * + * The board level statistics are read during a timer interrupt. + * Note that we read the error and operational statistics + * during consecitive timer ticks so as to minimize the time + * that we are inside the interrupt handler. + * + */ +static int update (wan_device_t* wandev) +{ + sdla_t* card = wandev->private; + netdevice_t* dev; + volatile private_area_t* chan; + + /* sanity checks */ + if((wandev == NULL) || (wandev->private == NULL)) + return -EFAULT; + + if(wandev->state == WAN_UNCONFIGURED) + return -ENODEV; + + if(wan_test_bit(PERI_CRIT, (void*)&card->wandev.critical)) + return -EAGAIN; + + dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head)); + if(dev == NULL) + return -ENODEV; + + if((chan=wan_netif_priv(dev)) == NULL) + return -ENODEV; + + if(card->update_comms_stats){ + return -EAGAIN; + } + + DEBUG_TEST("%s: Chain Dma Status=0x%lX, TxCur=%d, TxPend=%d RxCur=%d RxPend=%d\n", + chan->if_name, + chan->dma_chain_status, + chan->tx_chain_indx, + chan->tx_pending_chain_indx, + chan->rx_chain_indx, + chan->rx_pending_chain_indx); + +#if 1 + update_comms_stats(card); +#else + #warning "COMM STATS DISABLED" +#endif + return 0; +} + + + +/*============================================================================ + * new_if - Create new logical channel. + * + * &wandev: Wanpipe device pointer + * &dev: Network device pointer + * &conf: User configuration options pointer + * + * This routine is called by the ROUTER_IFNEW ioctl, + * in wanmain.c. The ioctl passes us the user configuration + * options which we use to configure the driver and + * firmware. + * + * This functions main purpose is to allocate the + * private structure for protocol and bind it + * to dev->priv pointer. + * + * Also the dev->init pointer should also be initialized + * to the if_init() function. + * + * Any allocation necessary for the private strucutre + * should be done here, as well as proc/ file initializetion + * for the network interface. + * + * o parse media- and hardware-specific configuration + * o make sure that a new channel can be created + * o allocate resources, if necessary + * o prepare network device structure for registaration. + * o add network interface to the /proc/net/wanrouter + * + * The opposite of this function is del_if() + * + * Return: 0 o.k. + * < 0 failure (channel will not be created) + */ + +static int +aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) +{ +#ifdef AFT_TDM_API_SUPPORT + int err=0; +#endif + + if (chan->common.usedby != TDM_VOICE_API && + chan->common.usedby != TDM_VOICE_DCHAN) { + return 0; + } + +#ifdef AFT_TDM_API_SUPPORT + if (chan->tdmv_zaptel_cfg) { + return 0; + } + + /* Initilaize TDM API Parameters */ + chan->wp_tdm_api_dev.chan = chan; + chan->wp_tdm_api_dev.card = card; + wan_spin_lock_init(&chan->wp_tdm_api_dev.lock); + strncpy(chan->wp_tdm_api_dev.name,chan->if_name,WAN_IFNAME_SZ); + + if (conf->hdlc_streaming) { + chan->wp_tdm_api_dev.hdlc_framing=1; + } + + chan->wp_tdm_api_dev.event_ctrl = aft_event_ctrl; + chan->wp_tdm_api_dev.read_rbs_bits = aft_read_rbs_bits; + chan->wp_tdm_api_dev.write_rbs_bits = aft_write_rbs_bits; + chan->wp_tdm_api_dev.write_hdlc_frame = aft_write_hdlc_frame; + + chan->wp_tdm_api_dev.cfg.rx_disable = 0; + chan->wp_tdm_api_dev.cfg.tx_disable = 0; + + if (IS_TE1_CARD(card)) { + if (IS_T1_CARD(card)){ + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_MULAW; + chan->wp_tdm_api_dev.tdm_chan = chan->first_time_slot+1; + }else{ + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_ALAW; + chan->wp_tdm_api_dev.tdm_chan = chan->first_time_slot; + } + } else { + if (card->fe.fe_cfg.tdmv_law == WAN_TDMV_MULAW){ + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_MULAW; + chan->wp_tdm_api_dev.tdm_chan = chan->first_time_slot+1; + } else { + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_ALAW; + chan->wp_tdm_api_dev.tdm_chan = chan->first_time_slot+1; + } + } + + if (IS_T1_CARD(card) || IS_FXOFXS_CARD(card)){ + /* Convert active_ch bit map to user */ + chan->wp_tdm_api_dev.active_ch = conf->active_ch << 1; + }else{ + chan->wp_tdm_api_dev.active_ch = conf->active_ch; + } + + chan->wp_tdm_api_dev.cfg.idle_flag = conf->u.aft.idle_flag; + chan->wp_tdm_api_dev.cfg.rbs_tx_bits = conf->u.aft.rbs_cas_idle; + + chan->wp_tdm_api_dev.tdm_span = card->tdmv_conf.span_no; + + err=wanpipe_tdm_api_reg(&chan->wp_tdm_api_dev); + if (err){ + return err; + } + + wan_set_bit(0,&chan->wp_tdm_api_dev.init); + return err; +#else + DEBUG_EVENT("%s: TDM API support not compiled in\n", + card->devname); + return -EINVAL; +#endif + +} + +static int aft_tdm_api_free(sdla_t *card, private_area_t *chan) +{ +#ifdef AFT_TDM_API_SUPPORT + int err=0; + if (wan_test_bit(0,&chan->wp_tdm_api_dev.init)){ + wan_clear_bit(0,&chan->wp_tdm_api_dev.init); + err=wanpipe_tdm_api_unreg(&chan->wp_tdm_api_dev); + if (err){ + wan_set_bit(0,&chan->wp_tdm_api_dev.init); + return err; + } + } +#endif + return 0; +} + + + +static int aft_chan_if_init(sdla_t *card, netdevice_t *dev, private_area_t *chan) +{ + chan->first_time_slot=-1; + chan->last_time_slot=-1; + chan->logic_ch_num=-1; +#if defined(AFT_SINGLE_DMA_CHAIN) + chan->single_dma_chain=1; + chan->max_tx_bufs=MAX_AFT_DMA_CHAINS; +#else + chan->single_dma_chain=0; + chan->max_tx_bufs=MAX_TX_BUF; +#endif + chan->tslot_sync=0; + + strncpy(chan->if_name, wan_netif_name(dev), WAN_IFNAME_SZ); + + chan->card = card; + chan->common.card = card; + + WAN_IFQ_INIT(&chan->wp_tx_pending_list,0); + WAN_IFQ_INIT(&chan->wp_tx_complete_list,0); + + WAN_IFQ_INIT(&chan->wp_rx_free_list,0); + WAN_IFQ_INIT(&chan->wp_rx_complete_list,0); + + WAN_IFQ_INIT(&chan->wp_rx_stack_complete_list, 0); + + wan_trace_info_init(&chan->trace_info,MAX_TRACE_QUEUE); + + /* Initiaize Tx/Rx DMA Chains */ + aft_index_tx_rx_dma_chains(chan); + + /* Initialize the socket binding information + * These hooks are used by the API sockets to + * bind into the network interface */ + WAN_TASKLET_INIT((&chan->common.bh_task),0,wp_bh,chan); + chan->common.dev = dev; + chan->tracing_enabled = 0; + + return 0; +} + + + +static int aft_ss7_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) +{ + if (chan->common.usedby != API){ + /* SS7 Support not supported in non API mode */ + chan->cfg.ss7_enable = 0; + return 0; + } + + DEBUG_EVENT("%s: SS7 Support :%s\n", + card->devname, + chan->cfg.ss7_enable?"On":"Off"); + + if (chan->cfg.ss7_enable){ + + wan_smp_flag_t smp_flags; + u32 lcfg_reg; + + DEBUG_EVENT("%s: SS7 Mode :%s\n", + card->devname, + chan->cfg.ss7_mode?"4096":"128"); + + DEBUG_EVENT("%s: SS7 LSSU Size :%d\n", + card->devname, + chan->cfg.ss7_lssu_size); + + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), + &lcfg_reg); + if (chan->cfg.ss7_mode){ + aft_lcfg_ss7_mode4096_cfg(&lcfg_reg,chan->cfg.ss7_lssu_size); + }else{ + aft_lcfg_ss7_mode128_cfg(&lcfg_reg,chan->cfg.ss7_lssu_size); + } + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), + lcfg_reg); + card->u.aft.lcfg_reg=lcfg_reg; + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + + aft_hwdev[card->wandev.card_type].aft_fifo_adjust(card,AFT_TDMV_FIFO_LEVEL); + chan->single_dma_chain=1; + } + + return 0; +} + +static int aft_transp_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) +{ + unsigned char *buf; + + if (chan->mtu&0x03){ + DEBUG_EVENT("%s:%s: Error, Transparent MTU must be word aligned!\n", + card->devname,chan->if_name); + return -EINVAL; + } + + chan->max_idle_size=chan->mtu; + + if (chan->tslot_sync && chan->mtu%chan->num_of_time_slots){ + DEBUG_EVENT("%s:%s: Error, Sync Transparent MTU must be timeslot aligned!\n", + card->devname,chan->if_name); + + DEBUG_EVENT("%s:%s: Error, MTU=%d not multiple of %d timeslots!\n", + card->devname,chan->if_name, + chan->mtu,chan->num_of_time_slots); + + return -EINVAL; + } + + if (conf->protocol != WANCONFIG_LIP_ATM && + conf->protocol != WANCONFIG_LIP_KATM && + chan->mru%chan->num_of_time_slots){ + DEBUG_EVENT("%s:%s: Error, Transparent MRU must be timeslot aligned!\n", + card->devname,chan->if_name); + + DEBUG_EVENT("%s:%s: Error, MRU=%d not multiple of %d timeslots!\n", + card->devname,chan->if_name, + chan->mru,chan->num_of_time_slots); + + return -EINVAL; + } + + + DEBUG_TEST("%s:%s: Config for Transparent mode: Idle=%X Len=%u\n", + card->devname,chan->if_name, + chan->idle_flag,chan->max_idle_size); + + chan->idle_flag=0x7E; + + if (chan->tdmv_zaptel_cfg){ +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + chan->idle_flag = WAN_TDMV_IDLE_FLAG; +#endif + } + + /* We use the dma_mru value here, just because it will + * be easier to change the idle tx size on the fly */ + chan->tx_idle_skb = wan_skb_alloc(chan->dma_mru); + if (!chan->tx_idle_skb){ + return -EINVAL; + } + buf = wan_skb_put(chan->tx_idle_skb,chan->dma_mru); + + if(conf->protocol != WANCONFIG_LIP_ATM && + conf->protocol != WANCONFIG_LIP_KATM){ + memset(buf,chan->idle_flag,chan->dma_mru); + }else{ + chan->lip_atm = 1; + /* if running below LIP ATM, transmit idle cells */ + if(init_atm_idle_buffer((unsigned char*)buf, + wan_skb_len(chan->tx_idle_skb), + chan->if_name, + chan->cfg.data_mux )){ + + wan_skb_free(chan->tx_idle_skb); + chan->tx_idle_skb = NULL; + return -EINVAL; + } + } + + /* reset the tx idle buffer to the actual mtu size */ + wan_skb_init(chan->tx_idle_skb,16); + wan_skb_trim(chan->tx_idle_skb,0); + wan_skb_put(chan->tx_idle_skb,chan->max_idle_size); + + return 0; +} + + +static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf, int channelized, int dchan) +{ + sdla_t* card = wandev->private; + private_area_t* chan; + int dma_per_ch=card->u.aft.cfg.dma_per_ch; + int err = 0; + + DEBUG_EVENT( "%s: Configuring Interface: %s\n", + card->devname, wan_netif_name(dev)); + + if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)){ + DEBUG_EVENT( "%s: Invalid interface name!\n", + card->devname); + return -EINVAL; + } + + + if (card->adptr_subtype != AFT_SUBTYPE_SHARK){ + if (card->u.aft.security_id != 0x01 && + card->u.aft.security_cnt >= 2){ + DEBUG_EVENT("%s: Error: Security: Max HDLC channels(2) exceeded!\n", + card->devname); + DEBUG_EVENT("%s: Un-Channelised AFT supports 2 HDLC ifaces!\n", + card->devname); + return -EINVAL; + } + } + + /* ====================================== + * Allocate and initialize private data + * =====================================*/ + + chan = wan_kmalloc(sizeof(private_area_t)); + if(chan == NULL){ + WAN_MEM_ASSERT(card->devname); + return -ENOMEM; + } + + memset(chan, 0, sizeof(private_area_t)); + memcpy(&chan->cfg,&conf->u.aft,sizeof(chan->cfg)); + + + chan->true_if_encoding=conf->true_if_encoding; + + aft_chan_if_init(card,dev,chan); + + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG) { + chan->single_dma_chain = 1; + conf->hdlc_streaming=0; + } + + if(IS_56K_CARD(card)){ + chan->single_dma_chain = 1; + conf->hdlc_streaming=1; + } + + if (channelized){ + chan->channelized_cfg=1; + if (wan_netif_priv(dev)){ +#if 1 + private_area_t *cptr; + for (cptr=wan_netif_priv(dev);cptr->next!=NULL;cptr=cptr->next); + cptr->next=chan; + chan->next=NULL; +#else +#warning "DEBUG: Chan list backwards!" + chan->next = wan_netif_priv(dev); + wan_netif_set_priv(dev, chan); +#endif + }else{ + wan_netif_set_priv(dev, chan); + } + }else{ + chan->channelized_cfg=0; + wan_netif_set_priv(dev, chan); + } + + /* ====================================== + * Configure chan MTU and MRU Values + * And setup E1 timeslots + * =====================================*/ + chan->mtu = card->wandev.mtu; + if (conf->u.aft.mtu){ + chan->mtu=conf->u.aft.mtu; + if (chan->mtu > MAX_WP_PRI_MTU || + chan->mtu < MIN_WP_PRI_MTU){ + DEBUG_EVENT("%s: Error Invalid %s MTU %d (Min=%d, Max=%d)\n", + card->devname,chan->if_name,chan->mtu, + MIN_WP_PRI_MTU,MAX_WP_PRI_MTU); + + err= -EINVAL; + goto new_if_error; + } + + } + + chan->mru = card->u.aft.cfg.mru; + if (conf->u.aft.mru){ + chan->mru = conf->u.aft.mru; + if (chan->mru > MAX_WP_PRI_MTU || + chan->mru < MIN_WP_PRI_MTU){ + DEBUG_EVENT("%s: Error Invalid %s MRU %d (Min=%d, Max=%d)\n", + card->devname,chan->if_name,chan->mru, + MIN_WP_PRI_MTU,MAX_WP_PRI_MTU); + + err= -EINVAL; + goto new_if_error; + } + } + + /*==================================================== + * Interface connects top services to driver + * Interface can be used by the following services: + * WANPIPE = TCP/IP -> Driver + * API = Raw Socket Access -> Driver + * BRIDGE = Bridge to Ethernet -> Driver + * BRIDGE_NODE = TCP/IP to Ethernet -> Driver + * STACK = LIP -> Driver + * TDM_VOICE = Zaptel -> Trans Ch Driver + * TDM_VOICE_DCHAN = Zaptel -> Hdlc Driver (PRIVATE) + * TDM_VOICE_API = Raw Socket -> Transp Ch Driver + * TMD_API = Raw Socket -> Transp Channelized API + *===================================================*/ + + if(strcmp(conf->usedby, "WANPIPE") == 0) { + + DEBUG_EVENT( "%s: Running in WANPIPE mode\n", + wandev->name); + chan->common.usedby = WANPIPE; + + /* Used by GENERIC driver only otherwise protocols + * are in LIP layer */ + if (conf->protocol != WANOPT_NO){ + wan_netif_set_priv(dev, chan); + if ((err=protocol_init(card,dev,chan,conf)) != 0){ + wan_netif_set_priv(dev, NULL); + goto new_if_error; + } + } + +#if defined(__LINUX__) + + } else if( strcmp(conf->usedby, "TDM_API") == 0) { + + DEBUG_EVENT("%s:%s: Error: TDM API mode is not supported!\n", + card->devname,chan->if_name); + err=-EINVAL; + goto new_if_error; +#endif + +#if defined(AFT_API_SUPPORT) + } else if( strcmp(conf->usedby, "API") == 0) { + chan->common.usedby = API; + DEBUG_EVENT( "%s:%s: Running in API mode\n", + wandev->name,chan->if_name); + wan_reg_api(chan, dev, card->devname); + card->wandev.event_callback.dtmf = wan_aft_api_dtmf; + card->wandev.event_callback.hook = wan_aft_api_hook; + card->wandev.event_callback.ringtrip = wan_aft_api_ringtrip; + card->wandev.event_callback.ringdetect = wan_aft_api_ringdetect; +#endif + +#if defined(__LINUX__) + }else if (strcmp(conf->usedby, "BRIDGE") == 0) { + chan->common.usedby = BRIDGE; + DEBUG_EVENT( "%s:%s: Running in WANPIPE (BRIDGE) mode.\n", + card->devname,chan->if_name); +#endif + +#if defined(__LINUX__) + }else if (strcmp(conf->usedby, "BRIDGE_N") == 0) { + chan->common.usedby = BRIDGE_NODE; + DEBUG_EVENT( "%s:%s: Running in WANPIPE (BRIDGE_NODE) mode.\n", + card->devname,chan->if_name); +#endif + + }else if (strcmp(conf->usedby, "TDM_VOICE") == 0) { + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + chan->common.usedby = TDM_VOICE; + + chan->tdmv_zaptel_cfg=1; + card->u.aft.tdmv_zaptel_cfg=1; + conf->hdlc_streaming=0; + chan->single_dma_chain=1; + chan->max_tx_bufs=MAX_AFT_DMA_CHAINS; + + if (dchan >= 0){ +# ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN + chan->common.usedby = TDM_VOICE_DCHAN; + conf->hdlc_streaming=1; + chan->single_dma_chain=0; + chan->mru=chan->mtu=1500; +# else + DEBUG_EVENT("%s: Error: TDMV_DCHAN Option not compiled into the driver!\n", + card->devname); + err=-EINVAL; + goto new_if_error; +# endif + } + + DEBUG_EVENT( "%s:%s: Running in TDM %sVoice Zaptel Mode.\n", + card->devname,chan->if_name, + chan->common.usedby == TDM_VOICE_DCHAN?"DCHAN ":""); +#else + DEBUG_EVENT("\n"); + DEBUG_EVENT("%s:%s: Error: TDM VOICE prot not compiled\n", + card->devname,chan->if_name); + DEBUG_EVENT("%s:%s: during installation process!\n", + card->devname,chan->if_name); + err=-EINVAL; + goto new_if_error; +#endif + +#if defined(__LINUX__) + }else if (strcmp(conf->usedby, "TDM_VOICE_API") == 0) { + + chan->common.usedby = TDM_VOICE_API; + chan->cfg.data_mux=1; + conf->hdlc_streaming=0; + chan->single_dma_chain=1; + chan->tdmv_zaptel_cfg=0; + + if (dchan >= 0){ + chan->common.usedby = TDM_VOICE_DCHAN; + chan->cfg.data_mux=0; + chan->single_dma_chain=0; + conf->hdlc_streaming=1; + chan->mru=chan->mtu=1500; + } + + + if (chan->common.usedby == TDM_VOICE_DCHAN) { + DEBUG_EVENT( "%s:%s: Running in TDM Voice DCHAN API Mode.\n", + card->devname,chan->if_name); + } else { + DEBUG_EVENT( "%s:%s: Running in TDM Voice API Mode.\n", + card->devname,chan->if_name); + } +#endif + + }else if (strcmp(conf->usedby, "STACK") == 0) { + chan->common.usedby = STACK; + DEBUG_EVENT( "%s:%s: Running in Stack mode.\n", + card->devname,chan->if_name); + + }else{ + DEBUG_EVENT( "%s:%s: Error: Invalid IF operation mode %s\n", + card->devname,chan->if_name,conf->usedby); + err=-EINVAL; + goto new_if_error; + } + + + /*=============================================== + * Interface Operation Setup + *==============================================*/ + + if (conf->hwec.enable){ + card->wandev.ec_enable_map |= conf->active_ch; + } + + /* Read user specified active_ch, we must do it + * here because the active_ch value might change + * for different user modes*/ + chan->time_slot_map=conf->active_ch; + chan->num_of_time_slots= + aft_get_num_of_slots(card->u.aft.num_of_time_slots, + chan->time_slot_map); + + if (!chan->num_of_time_slots){ + DEBUG_EVENT("%s: Error: Invalid number of timeslots in map 0x%08lX!\n", + chan->if_name,chan->time_slot_map); + return -EINVAL; + } + + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG && chan->num_of_time_slots > 1) { + DEBUG_EVENT( + "%s: Error: Invalid Analog number of timeslots in map 0x%08lX: (Valid=1)\n", + chan->if_name,chan->time_slot_map); + return -EINVAL; + } + + + /* ===================== + * Interaface TDMV Setup + * + * Initialize the interface for TDMV + * operation, if TDMV is not used this + * function will just return */ + err=aft_tdmv_if_init(card,chan,conf); + if (err){ + err=-EINVAL; + goto new_if_error; + } + + + /* ===================== + * Interaface SS7 Setup + * + * Initialize the interface for TDMV + * operation, if TDMV is not used this + * function will just return */ + err=aft_ss7_if_init(card,chan,conf); + if (err){ + err=-EINVAL; + goto new_if_error; + } + + + /* Print out the current configuration */ + DEBUG_EVENT("%s: MRU :%d\n", + card->devname, + chan->mru); + + DEBUG_EVENT("%s: MTU :%d\n", + card->devname, + chan->mtu); + + + chan->hdlc_eng = conf->hdlc_streaming; + + DEBUG_EVENT("%s: HDLC Eng :%s\n", + card->devname, + chan->hdlc_eng?"On":"Off (Transparent)"); + + + /* Obtain the DMA MRU size based on user confgured + * MRU. The DMA MRU must be of size 2^x */ + + chan->dma_mru = chan->mtu; + +#if defined(__LINUX__) + chan->dma_mru = aft_valid_mtu(chan->dma_mru); +#else + chan->dma_mru = aft_valid_mtu(chan->dma_mru); +#endif + if (!chan->dma_mru){ + DEBUG_EVENT("%s:%s: Error invalid MTU %d MRU %d\n", + card->devname, + chan->if_name, + chan->mtu,chan->mru); + err= -EINVAL; + goto new_if_error; + } + + if (conf->single_tx_buf || + ((card->adptr_type == A101_ADPTR_2TE1 || card->adptr_type == A101_ADPTR_1TE1) && + card->u.aft.firm_id == AFT_DS_FE_CORE_ID)){ + chan->single_dma_chain=1; + chan->max_tx_bufs=MAX_AFT_DMA_CHAINS; + dma_per_ch=MAX_AFT_DMA_CHAINS; + } + + + if (!chan->hdlc_eng){ + /* If hardware HDLC engine is disabled: + * 1. Configure DMA chains for SINGLE DMA + * 2. Enable Timeslot Synchronization + * 3. Configure Interface for Transparent Operation */ + chan->single_dma_chain=1; + chan->max_tx_bufs=MAX_AFT_DMA_CHAINS; + + if (chan->channelized_cfg) { + dma_per_ch=MAX_AFT_DMA_CHAINS; + }else{ + dma_per_ch= (MAX_AFT_DMA_CHAINS*1500) / chan->mtu; + if (dma_per_ch < MAX_AFT_DMA_CHAINS) { + dma_per_ch=MAX_AFT_DMA_CHAINS; + } + } + + chan->tslot_sync=1; + + if(conf->protocol == WANCONFIG_LIP_ATM || + conf->protocol == WANCONFIG_LIP_KATM){ + chan->tslot_sync=0; + } + + err=aft_transp_if_init(card,chan,conf); + if (err){ + goto new_if_error; + } + + }else{ + /* If hardware HDLC engine is enabled: + * 1. Force Disable DATA MUX option + * just in case user made a mistake + */ + chan->cfg.data_mux=0; + } + DEBUG_EVENT("%s: Data Mux Ctrl :%s\n", + card->devname, + chan->cfg.data_mux?"On":"Off"); + + + + + /*================================================= + * AFT CHANNEL Configuration + * + * Configure the AFT Hardware for this + * logic channel. Enable the above selected + * operation modes. + *================================================*/ + + err=aft_dev_configure(card,chan,conf); + if (err){ + goto new_if_error; + } + + /*Set the actual logic ch number of this chan + *as the dchan. Due to HDLC security issue, the + *HDLC channels are mapped on first TWO logic channels */ + if (chan->common.usedby == TDM_VOICE_DCHAN){ + card->u.aft.tdmv_dchan=chan->logic_ch_num+1; + } + + /* Configure the DCHAN on LAST Master interface. + * We will use the master interface information, until + * the next interface with the current DCHAN info is + * configured. This must be done in order to register + * the DCHAN in zaptel. */ + if (card->u.aft.tdmv_dchan_cfg_on_master && + card->u.aft.tdmv_dchan){ + int dchan=card->u.aft.tdmv_dchan; + if (IS_T1_CARD(card)){ + dchan--; + } + if (wan_test_bit(dchan,&conf->active_ch)){ + DEBUG_EVENT("%s: TDMV DCHAN :%d\n", + card->devname,dchan); + card->u.aft.tdmv_chan_ptr=chan; + card->u.aft.tdmv_dchan=chan->logic_ch_num+1; + } + } + + + err=aft_tdm_api_init(card,chan,conf); + if (err){ + goto new_if_error; + } + + err=aft_hwec_config(card,chan,conf,1); + if (err){ + goto new_if_error; + } + + if (chan->channelized_cfg && !chan->hdlc_eng) { + chan->dma_mru = 1024; + dma_per_ch = 4; + } + + DEBUG_EVENT("%s: DMA/Len/Chain/EC :%d/%d/%s/%s\n", + card->devname, + dma_per_ch, + chan->dma_mru, + chan->single_dma_chain?"Off":"On", + card->wandev.ec_enable_map?"On":"Off"); + + + + err=aft_alloc_rx_dma_buff(card, chan, dma_per_ch,0); + if (err){ + goto new_if_error; + } + + /*======================================================= + * Interface OS Specific Configuration + *======================================================*/ + + + /* If gateway option is set, then this interface is the + * default gateway on this system. We must know that information + * in case DYNAMIC interface configuration is enabled. + * + * I.E. If the interface is brought down by the driver, the + * default route will also be removed. Once the interface + * is brought back up, we must know to re-astablish the + * default route. + */ + if ((chan->gateway = conf->gateway) == WANOPT_YES){ + DEBUG_EVENT( "%s: Interface %s is set as a gateway.\n", + card->devname,chan->if_name); + } + + /* Get Multicast Information from the user + * FIXME: This is IP relevant, since this is now + * a hardware interface this option should't + * be here */ + chan->mc = conf->mc; + + + /* The network interface "dev" has been passed as + * an argument from the above layer. We must initialize + * it so it can be registered into the kernel. + * + * The "dev" structure is the link between the kernel + * stack and the wanpipe driver. It contains all + * access hooks that kernel uses to communicate to + * the our driver. + * + * For now, just set the "dev" name to the user + * defined name and initialize: + * dev->if_init : function that will be called + * to further initialize + * dev structure on "ifconfig up" + * + * dev->priv : private structure allocated above + * + */ + + + /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * DO NOT PLACE ANY CODE BELOW THAT COULD RETURN ERROR + * + *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ + + + /* Only setup the dev pointer once the new_if function has + * finished successfully. DO NOT place any code below that + * can return an error */ +#if defined(__LINUX__) + dev->init = &if_init; +# if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) + if_init(dev); +# endif +#else + chan->common.is_netdev = 1; + chan->common.iface.open = &if_open; + chan->common.iface.close = &if_close; + chan->common.iface.output = &if_send; + chan->common.iface.ioctl = &if_do_ioctl; + chan->common.iface.get_stats = &if_stats; + chan->common.iface.tx_timeout= &if_tx_timeout; + if (wan_iface.attach){ + if (!ifunit(wan_netif_name(dev))){ + wan_iface.attach(dev, NULL, chan->common.is_netdev); + } + }else{ + DEBUG_EVENT("%s: Failed to attach interface %s!\n", + card->devname, wan_netif_name(dev)); + wan_netif_set_priv(dev, NULL); + err = -EINVAL; + goto new_if_error; + } + wan_netif_set_mtu(dev, chan->mtu); +#endif + + /* + * Increment the number of network interfaces + * configured on this card. + */ + wan_atomic_inc(&card->wandev.if_cnt); + if (chan->hdlc_eng){ + ++card->u.aft.security_cnt; + } + + + + /* Keep the original tx queue len in case + we have to go back to it */ + chan->max_tx_bufs_orig = chan->max_tx_bufs; + + chan->common.state = WAN_CONNECTING; + + DEBUG_EVENT( "\n"); + + return 0; + +new_if_error: + + return err; +} + +static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) +{ + int err=-EINVAL; + sdla_t *card=wandev->private; + + wan_netif_set_priv(dev, NULL); + + if (IS_E1_CARD(card) && !(WAN_FE_FRAME(&card->fe) == WAN_FR_UNFRAMED)) { + conf->active_ch = conf->active_ch << 1; + wan_clear_bit(0,&conf->active_ch); + }else if (IS_56K_CARD(card)) { + conf->active_ch = 1; + } + + + if (strcmp(conf->usedby, "TDM_VOICE") == 0) { +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (card->tdmv_conf.span_no){ + + switch(card->wandev.config_id){ + case WANCONFIG_AFT_ANALOG: + err = wp_tdmv_remora_init(&card->tdmv_iface); + break; + default: + err = wp_tdmv_te1_init(&card->tdmv_iface); + break; + } + if (err){ + DEBUG_EVENT("%s: Error: Failed to initialize tdmv functions!\n", + card->devname); + return -EINVAL; + } + + WAN_TDMV_CALL(create, (card, &card->tdmv_conf), err); + if (err){ + DEBUG_EVENT("%s: Error: Failed to create tdmv span!\n", + card->devname); + return err; + } + } +#else + DEBUG_EVENT("\n"); + DEBUG_EVENT("%s: Error: TDM VOICE prot not compiled\n", + card->devname); + DEBUG_EVENT("%s: during installation process!\n", + card->devname); + return -EINVAL; +#endif + } + + err=-EINVAL; + + if (strcmp(conf->usedby, "TDM_VOICE") == 0 || + strcmp(conf->usedby, "TDM_VOICE_API") == 0){ + + int i=0,master_if=-1; + u32 active_ch=conf->active_ch; + + if (card->wandev.fe_iface.active_map){ + conf->active_ch = card->wandev.fe_iface.active_map(&card->fe); + active_ch=conf->active_ch; + } + + err=aft_find_master_if_and_dchan(card,&master_if,active_ch); + if (err < 0) { + return err; + } + + DEBUG_TEST("%s: TDM VOICE: TESTING FOR DCHAN CHAN in 0x%08X Timeslots=%i CFG DCHAN=0x%08X MasterIF=%i\n", + card->devname, active_ch, card->u.aft.num_of_time_slots, + card->tdmv_conf.dchan,master_if); + + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&active_ch)){ + int dchan=-1; + conf->active_ch=0; + conf->u.aft.tdmv_master_if=0; + wan_set_bit(i,&conf->active_ch); + if (wan_test_bit(i,&card->tdmv_conf.dchan)){ + dchan=i; + } + if (i==master_if){ + conf->u.aft.tdmv_master_if=1; + } + + err=new_if_private(wandev,dev,conf,1,dchan); + if (err){ + break; + } + } + } + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (!err && card->u.aft.tdmv_zaptel_cfg){ + WAN_TDMV_CALL(software_init, (&card->wan_tdmv), err); + } +#endif + + }else{ + card->tdmv_conf.dchan=0; + err=new_if_private(wandev,dev,conf,0,-1); + } + + + if (err == 0 && wan_netif_priv(dev)) { + wan_smp_flag_t flags; + + /* If FRONT End is down, it means that the DMA + * is disabled. In this case don't try to + * reset fifo. Let the enable_data_error_intr() + * function do this, after front end has come up */ + + wan_spin_lock_irq(&card->wandev.lock,&flags); + + aft_dev_open(card, wan_netif_priv(dev)); + + if (card->wandev.state == WAN_CONNECTED){ + set_chan_state(card, dev, WAN_CONNECTED); + } + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG) { + wan_spin_lock_irq(&card->wandev.lock,&flags); + card->fe.fe_status = FE_CONNECTED; + handle_front_end_state(card); + set_chan_state(card, dev, WAN_CONNECTED); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + } + + } else if (err && wan_netif_priv(dev)){ + del_if(wandev,dev); + if (wan_netif_priv(dev)){ + wan_free(wan_netif_priv(dev)); + wan_netif_set_priv(dev, NULL); + } + } + + return err; +} + + +/*============================================================================ + * del_if - Delete logical channel. + * + * @wandev: Wanpipe private device pointer + * @dev: Netowrk interface pointer + * + * This function is called by ROUTER_DELIF ioctl call + * to deallocate the network interface. + * + * The network interface and the private structure are + * about to be deallocated by the upper layer. + * We have to clean and deallocate any allocated memory. + * + * NOTE: DO NOT deallocate dev->priv here! It will be + * done by the upper layer. + * + */ +static int del_if_private (wan_device_t* wandev, netdevice_t* dev) +{ + private_area_t* chan = wan_netif_priv(dev); + sdla_t* card; + netskb_t *skb; + wan_smp_flag_t flags; + + if (!chan){ + DEBUG_EVENT("%s: Critical Error del_if_private() chan=NULL!\n", + wan_netif_name(dev)); + return 0; + } + + card = chan->card; + if (!card){ + DEBUG_EVENT("%s: Critical Error del_if_private() chan=NULL!\n", + wan_netif_name(dev)); + return 0; + } + + aft_hwec_config(card,chan,NULL,0); + + wan_spin_lock_irq(&card->wandev.lock,&flags); + aft_dev_unconfigure(card,chan); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + AFT_FUNC_DEBUG(); +#if INIT_FE_ONLY + return 0; +#endif + + WAN_TASKLET_KILL(&chan->common.bh_task); + + if (chan->common.usedby == API){ + wan_unreg_api(chan, card->devname); + + } + + if (aft_tdm_api_free(card,chan)) { + DEBUG_EVENT("%s: Error: Failed to del iface: TDM API Device in use!\n", + chan->if_name); + return -EBUSY; + } + + wan_spin_lock_irq(&card->wandev.lock,&flags); + aft_tdmv_if_free(card,chan); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + protocol_shutdown(card,dev); + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + if (wan_iface.detach){ + wan_iface.detach(dev, chan->common.is_netdev); + } +#endif + + /* We must set used by to API because + * the free_tx and free_rx are not allowed + * for TDM_VOICE mode in regular operation */ + + + wan_spin_lock_irq(&card->wandev.lock,&flags); + + chan->common.usedby = API; + + aft_free_tx_descriptors(chan); + aft_free_rx_descriptors(chan); + + while ((skb=wan_skb_dequeue(&chan->wp_rx_free_list)) != NULL) { +#ifdef __LINUX__ + if (skb_shinfo(skb)->frag_list || + skb_shinfo(skb)->nr_frags) { + DEBUG_EVENT("%s: Warning: SKB Corruption ch=%li!\n", + chan->if_name,chan->logic_ch_num); + continue; + } +#endif + wan_skb_free(skb); + } + + while ((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ + wan_skb_free(skb); + } + + while ((skb=wan_skb_dequeue(&chan->wp_rx_stack_complete_list)) != NULL){ + wan_skb_free(skb); + } + + while ((skb=wan_skb_dequeue(&chan->wp_tx_pending_list)) != NULL){ + wan_skb_free(skb); + } + + while ((skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ + wan_skb_free(skb); + } + + + if (chan->tx_idle_skb){ + wan_skb_free(chan->tx_idle_skb); + chan->tx_idle_skb=NULL; + } + + if (chan->tx_realign_buf){ + wan_free(chan->tx_realign_buf); + chan->tx_realign_buf=NULL; + } + + if (chan->tx_ss7_realign_buf){ + wan_free(chan->tx_ss7_realign_buf); + chan->tx_ss7_realign_buf=NULL; + } + + if (card->u.aft.tdmv_chan_ptr == chan){ + card->u.aft.tdmv_chan_ptr=NULL; + } + + chan->logic_ch_num=-1; + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + /* Delete interface name from proc fs. */ +#if 0 + wanrouter_proc_delete_interface(wandev, chan->if_name); +#endif + + /* Decrement the number of network interfaces + * configured on this card. + */ + wan_atomic_dec(&card->wandev.if_cnt); + if (chan->hdlc_eng){ + --card->u.aft.security_cnt; + } + + DEBUG_SUB_MEM(sizeof(private_area_t)); + return 0; +} + +static int del_if (wan_device_t* wandev, netdevice_t* dev) +{ + private_area_t* chan=wan_netif_priv(dev); + wan_smp_flag_t flags; + sdla_t *card; + + if (!chan){ + DEBUG_EVENT("%s: Critical Error del_if() chan=NULL!\n", + wan_netif_name(dev)); + return 0; + } + + if (!(card=chan->card)){ + DEBUG_EVENT("%s: Critical Error del_if() chan=NULL!\n", + wan_netif_name(dev)); + return 0; + } + + wan_spin_lock_irq(&card->wandev.lock,&flags); + aft_dev_close(card,chan); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + if (chan->channelized_cfg) { + + sdla_t *card=chan->card; + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (chan->tdmv_zaptel_cfg) { + sdla_t *card=chan->card; + int err; + WAN_TDMV_CALL(running, (card), err); + if (err){ + return -EBUSY; + } + } +#endif + + /* Disable the TDMV Interrupt first, before + * shutting down all TDMV channels */ + wan_spin_lock_irq(&card->wandev.lock,&flags); + + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); + + /* Disable RTP Tap */ + card->u.aft.rtp_len=0; + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc) { + int err; + WAN_TDMV_CALL(state, (card, WAN_DISCONNECTED), err); + } +#endif + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + while(chan){ + int err=del_if_private(wandev,dev); + if (err) { + return err; + } + if (chan->next) { + wan_netif_set_priv(dev, chan->next); + wan_free(chan); + chan = wan_netif_priv(dev); + } else { + /* Leave the last chan dev + * in dev->priv. It will get + * deallocated normally */ + break; + } + } + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc) { + aft_tdmv_free(card); + } +#endif + return 0; + } else { + return del_if_private(wandev,dev); + } +} + + +/**SECTION*********************************************************** + * + * KERNEL Device Entry Interfaces + * + ********************************************************************/ + + + +/*============================================================================ + * if_init - Initialize Linux network interface. + * + * @dev: Network interface pointer + * + * During "ifconfig up" the upper layer calls this function + * to initialize dev access pointers. Such as transmit, + * stats and header. + * + * It is called only once for each interface, + * during Linux network interface registration. + * + * Returning anything but zero will fail interface + * registration. + */ +#if defined(__LINUX__) +static int if_init (netdevice_t* dev) +{ + private_area_t* chan = wan_netif_priv(dev); + sdla_t* card = chan->card; + wan_device_t* wandev = &card->wandev; +#if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) + hdlc_device* hdlc; +#endif + + /* Initialize device driver entry points */ + dev->open = &if_open; + dev->stop = &if_close; +#if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) + hdlc = dev_to_hdlc(dev); + hdlc->xmit = if_send; +#else + dev->hard_start_xmit = &if_send; +#endif + dev->get_stats = &if_stats; + +#if 0 + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = 2*HZ; +#else + if (chan->common.usedby == TDM_VOICE || + chan->common.usedby == TDM_VOICE_DCHAN || + chan->common.usedby == TDM_VOICE_API){ + dev->tx_timeout = NULL; + }else{ + dev->tx_timeout = &if_tx_timeout; + } + dev->watchdog_timeo = 2*HZ; + +#endif + dev->do_ioctl = if_do_ioctl; + + if (chan->common.usedby == BRIDGE || + chan->common.usedby == BRIDGE_NODE){ + + /* Setup the interface for Bridging */ + int hw_addr=0; + ether_setup(dev); + + /* Use a random number to generate the MAC address */ + memcpy(dev->dev_addr, "\xFE\xFC\x00\x00\x00\x00", 6); + get_random_bytes(&hw_addr, sizeof(hw_addr)); + *(int *)(dev->dev_addr + 2) += hw_addr; + + }else{ + + dev->flags |= IFF_POINTOPOINT; + dev->flags |= IFF_NOARP; + dev->type = ARPHRD_PPP; + dev->mtu = chan->mtu; + dev->hard_header_len = 0; + dev->hard_header = NULL; + dev->rebuild_header = NULL; + + if (chan->common.usedby == API || chan->common.usedby == STACK){ + if (chan->hdlc_eng) { + dev->mtu = chan->dma_mru+sizeof(api_tx_hdr_t); + }else{ + dev->mtu = chan->mtu+sizeof(api_tx_hdr_t); + } + } + + /* Enable Mulitcasting if user selected */ + if (chan->mc == WANOPT_YES){ + dev->flags |= IFF_MULTICAST; + } + + if (chan->true_if_encoding){ + DEBUG_EVENT("%s: Setting IF Type to Broadcast\n",chan->if_name); + dev->type = ARPHRD_PPP; /* This breaks the tcpdump */ + dev->flags &= ~IFF_POINTOPOINT; + dev->flags |= IFF_BROADCAST; + }else{ + dev->type = ARPHRD_PPP; + } + } + + /* Initialize hardware parameters */ + dev->irq = wandev->irq; + dev->dma = wandev->dma; + dev->base_addr = wandev->ioport; + card->hw_iface.getcfg(card->hw, SDLA_MEMBASE, &dev->mem_start); + card->hw_iface.getcfg(card->hw, SDLA_MEMEND, &dev->mem_end); + + /* Set transmit buffer queue length + * If too low packets will not be retransmitted + * by stack. + */ + dev->tx_queue_len = 100; + return 0; +} +#endif + +/*============================================================================ + * if_open - Open network interface. + * + * @dev: Network device pointer + * + * On ifconfig up, this function gets called in order + * to initialize and configure the private area. + * Driver should be configured to send and receive data. + * + * This functions starts a timer that will call + * frmw_config() function. This function must be called + * because the IP addresses could have been changed + * for this interface. + * + * Return 0 if O.k. or errno. + */ +static int if_open (netdevice_t* dev) +{ + private_area_t* chan = wan_netif_priv(dev); + sdla_t* card = chan->card; + + + +#if defined(__LINUX__) + /* Only one open per interface is allowed */ + if (open_dev_check(dev)){ + DEBUG_EVENT("%s: Open dev check failed!\n", + wan_netif_name(dev)); + return -EBUSY; + } +#endif + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + DEBUG_EVENT("%s:%s: Card down: Failed to open interface!\n", + card->devname,chan->if_name); + return -EINVAL; + } + + + /* Initialize the router start time. + * Used by wanpipemon debugger to indicate + * how long has the interface been up */ + wan_getcurrenttime(&chan->router_start_time, NULL); + + WAN_NETIF_START_QUEUE(dev); + + if (card->wandev.state == WAN_CONNECTED){ + set_chan_state(card, dev, WAN_CONNECTED); + WAN_NETIF_CARRIER_ON(dev); + } else { + WAN_NETIF_CARRIER_OFF(dev); + } + + /* Increment the module usage count */ + wanpipe_open(card); + + + /* Wait for the front end interrupt + * before enabling the card */ + return 0; +} + +/*============================================================================ + * if_close - Close network interface. + * + * @dev: Network device pointer + * + * On ifconfig down, this function gets called in order + * to cleanup interace private area. + * + * IMPORTANT: + * + * No deallocation or unconfiguration should ever occur in this + * function, because the interface can come back up + * (via ifconfig up). + * + * Furthermore, in dynamic interfacace configuration mode, the + * interface will come up and down to reflect the protocol state. + * + * Any deallocation and cleanup can occur in del_if() + * function. That function is called before the dev interface + * itself is deallocated. + * + * Thus, we should only stop the net queue and decrement + * the wanpipe usage counter via wanpipe_close() function. + */ + +static int if_close (netdevice_t* dev) +{ + private_area_t* chan = wan_netif_priv(dev); + sdla_t* card = chan->card; + + WAN_NETIF_STOP_QUEUE(dev); + +#if defined(LINUX_2_1) + dev->start=0; +#endif + protocol_stop(card,dev); + + wanpipe_close(card); + + return 0; +} + + +/*============================================================= + * disable_comm - Main shutdown function + * + * @card: Wanpipe device pointer + * + * The command 'wanrouter stop' has been called + * and the whole wanpipe device is going down. + * This is the last function called to disable + * all comunications and deallocate any memory + * that is still allocated. + * + * o Disable communications, turn off interrupts + * o Deallocate memory used, if any + * o Unconfigure TE1 card + */ + +static void disable_comm (sdla_t *card) +{ + wan_smp_flag_t flags,flags1; + int used_cnt; + + AFT_FUNC_DEBUG(); +#if INIT_FE_ONLY + aft_chip_unconfigure(card); +#else + + /* Unconfiging, only on shutdown */ + if (IS_TE1_CARD(card) || IS_56K_CARD(card)) { + wan_smp_flag_t smp_flags,smp_flags1; + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + __aft_fe_intr_ctrl(card, 0); + if (card->wandev.fe_iface.unconfig){ + card->wandev.fe_iface.unconfig(&card->fe); + } + __aft_fe_intr_ctrl(card, 1); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + + } + + wan_spin_lock_irq(&card->wandev.lock,&flags); + + wan_set_bit(CARD_DOWN,&card->wandev.critical); + + /* Disable DMA ENGINE before we perform + * core reset. Otherwise, we will receive + * rx fifo errors on subsequent resetart. */ + disable_data_error_intr(card,DEVICE_DOWN); + + aft_rtp_unconfig(card); + + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + aft_chip_unconfigure(card); + + WP_DELAY(10); + + + card->hw_iface.getcfg(card->hw, SDLA_USEDCNT, &used_cnt); + + card->hw_iface.hw_lock(card->hw,&flags1); + wan_spin_lock_irq(&card->wandev.lock,&flags); + __aft_fe_intr_ctrl(card, 0); + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_ON); + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_ON); + __aft_fe_intr_ctrl(card, 1); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + card->hw_iface.hw_unlock(card->hw,&flags1); + + __sdla_pull_ptr_isr_array(card->hw,card,card->wandev.comm_port); + + if (used_cnt<=1){ + DEBUG_EVENT("%s: Global Chip Shutdown Usage=%d\n", + card->devname,used_cnt); + + wan_spin_lock_irq(&card->wandev.lock,&flags); + aft_global_chip_disable(card); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + } + + +#if defined(WAN_DEBUG_MEM) + DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); +#endif +#endif + return; +} + + + +/*============================================================================ + * if_tx_timeout + * + * Kernel networking stack calls this function in case + * the interface has been stopped for TX_TIMEOUT seconds. + * + * This would occur if we lost TX interrupts or the + * card has stopped working for some reason. + * + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout (netdevice_t *dev) +{ + private_area_t* chan = wan_netif_priv(dev); + private_area_t* ch_ptr; + sdla_t *card = chan->card; + unsigned int cur_dma_ptr; + u32 reg,dma_ram_desc; + wan_smp_flag_t smp_flags; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + ++chan->if_stats.collisions; + + DEBUG_EVENT( "%s: Transmit timed out on %s\n", + card->devname, + wan_netif_name(dev)); + + dma_ram_desc=chan->logic_ch_num*4+AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_tx_dma_addr(reg); + + DEBUG_EVENT("%s: Chain TxPend=%d, TxCur=%d, TxPend=%d HwCur=%d TxA=%d TxC=%ld\n", + chan->if_name, + wan_test_bit(TX_INTR_PENDING,&chan->dma_chain_status), + chan->tx_chain_indx, + chan->tx_pending_chain_indx, + cur_dma_ptr, + chan->tx_attempts, + chan->if_stats.tx_packets); + + if (wan_test_bit(TX_DMA_BUSY,&chan->dma_status)){ + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + } + + wan_netif_set_ticks(dev, SYSTEM_TICKS); + +#ifdef AFT_TX_FIFO_DEBUG + aft_list_tx_descriptors(chan); +#endif + + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + if (chan->channelized_cfg){ + for (ch_ptr=chan;ch_ptr;ch_ptr=ch_ptr->next){ + aft_tx_fifo_under_recover(card,chan); + } + }else{ + aft_tx_fifo_under_recover(card,chan); + } + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + +#ifdef AFT_TX_FIFO_DEBUG + aft_list_tx_descriptors(chan); +#endif + + WAN_NETIF_WAKE_QUEUE(dev); + if (chan->common.usedby == API){ + wan_wakeup_api(chan); + }else if (chan->common.usedby == STACK){ + wanpipe_lip_kick(chan,0); + }else if (chan->common.usedby == TDM_VOICE_DCHAN){ +#ifdef AFT_TDM_API_SUPPORT + if (is_tdm_api(chan,&chan->wp_tdm_api_dev)){ + wanpipe_tdm_api_kick(&chan->wp_tdm_api_dev); + } +#endif + } +} + + +/*============================================================================ + * if_send - Send a packet on a network interface. + * + * @dev: Network interface pointer + * @skb: Packet obtained from the stack or API + * that should be sent out the port. + * + * o Mark interface as stopped + * (marks start of the transmission) to indicate + * to the stack that the interface is busy. + * + * o Check link state. + * If link is not up, then drop the packet. + * + * o Copy the tx packet into the protocol tx buffers on + * the adapter. + * + * o If tx successful: + * Free the skb buffer and mark interface as running + * and return 0. + * + * o If tx failed, busy: + * Keep interface marked as busy + * Do not free skb buffer + * Enable Tx interrupt (which will tell the stack + * that interace is not busy) + * Return a non-zero value to tell the stack + * that the tx should be retried. + * + * Return: 0 complete (socket buffer must be freed) + * non-0 packet may be re-transmitted + * + */ +#if defined(__LINUX__) +static int if_send (netskb_t* skb, netdevice_t* dev) +#else +static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct rtentry *rt) +#endif +{ + private_area_t *chan = wan_netif_priv(dev); + sdla_t *card = chan->card; + int err; + wan_smp_flag_t smp_flags; + + /* Mark interface as busy. The kernel will not + * attempt to send any more packets until we clear + * this condition */ + + if (skb == NULL){ + /* This should never happen. Just a sanity check. + */ + DEBUG_EVENT( "%s: interface %s got kicked!\n", + card->devname, + wan_netif_name(dev)); + + WAN_NETIF_WAKE_QUEUE(dev); + return 0; + } + + /* Non 2.4 kernels used to call if_send() + * after TX_TIMEOUT seconds have passed of interface + * being busy. Same as if_tx_timeout() in 2.4 kernels */ +#if defined(LINUX_2_1) + if (dev->tbusy){ + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + ++chan->if_stats.collisions; + if((SYSTEM_TICKS - chan->tick_counter) < (5 * HZ)) { + return 1; + } + + if_tx_timeout(dev); + } +#endif + err=0; + + if (chan->common.state != WAN_CONNECTED){ +#if 1 + WAN_NETIF_STOP_QUEUE(dev); + wan_netif_set_ticks(dev, SYSTEM_TICKS); + ++chan->if_stats.tx_carrier_errors; + return 1; +#else + ++chan->if_stats.tx_carrier_errors; + wan_skb_free(skb); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; +#endif + } + + if (chan->channelized_cfg) { + + private_area_t *top_chan=wan_netif_priv(chan->common.dev); + + DEBUG_TEST("%s:%ld Prev: Zaptel HDLC Tt TDMV_DCHAN=%i\n", + chan->if_name,chan->logic_ch_num, + card->u.aft.tdmv_dchan-1); + + if (!card->u.aft.tdmv_dchan || card->u.aft.tdmv_dchan>32){ + + DEBUG_EVENT("%s: DCHAN TX No DCHAN Configured!\n", + card->devname); + + wan_skb_free(skb); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[card->u.aft.tdmv_dchan-1]; + if (!chan){ + DEBUG_EVENT("%s: DCHAN TX No DCHAN Configured by not preset!\n", + card->devname); + wan_skb_free(skb); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + if (!chan->hdlc_eng){ + wan_skb_free(skb); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + wan_capture_trace_packet(chan->card, &top_chan->trace_info, + skb,TRC_OUTGOING_FRM); + + DEBUG_TEST("%s:%ld Zaptel HDLC Tt TDMV_DCHAN=%i\n", + chan->if_name,chan->logic_ch_num, + card->u.aft.tdmv_dchan-1); + } + + /* For TDM_VOICE_API no tx is supported in if_send */ + if (chan->common.usedby == TDM_VOICE_API){ + ++chan->if_stats.tx_errors; + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + if (chan->common.usedby == API){ + + if (sizeof(api_tx_hdr_t) >= wan_skb_len(skb)){ + wan_skb_free(skb); + ++chan->if_stats.tx_errors; + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + if (chan->cfg.ss7_enable){ + err=aft_ss7_tx_mangle(card,chan,skb); + if (err){ + wan_skb_free(skb); + ++chan->if_stats.tx_errors; + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + }else{ + wan_skb_pull(skb,sizeof(api_tx_hdr_t)); + } + } + + if (!chan->hdlc_eng && chan->tslot_sync){ + if (wan_skb_len(skb)%chan->num_of_time_slots){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error pkt len(%d) not multiple of timeslots(%d)\n", + card->devname, + chan->if_name, + wan_skb_len(skb), + chan->num_of_time_slots); + } + wan_skb_free(skb); + ++chan->if_stats.tx_errors; + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + } + + if (!chan->hdlc_eng && !chan->lip_atm && (wan_skb_len(skb)%4)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Tx Error: Tx Length %i is not 32bit divisible\n", + chan->if_name,wan_skb_len(skb)); + } + wan_skb_free(skb); + ++chan->if_stats.tx_errors; + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + + if (wan_skb_queue_len(&chan->wp_tx_pending_list) > chan->max_tx_bufs){ +#warning "NENAD" + DEBUG_EVENT("%s: Tx BUSY \n", + chan->if_name); + WAN_NETIF_STOP_QUEUE(dev); + aft_dma_tx(card,chan); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + return 1; + + } + + wan_skb_unlink(skb); + + wan_skb_queue_tail(&chan->wp_tx_pending_list,skb); + + if(!chan->lip_atm){ + aft_dma_tx(card,chan); /*not needed for LIP_ATM!!*/ + } + + + wan_netif_set_ticks(dev, SYSTEM_TICKS); + WAN_NETIF_START_QUEUE(dev); + err=0; + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + +#if defined(__LINUX__) + if (dev->tx_queue_len < chan->max_tx_bufs && + dev->tx_queue_len > 0) { + DEBUG_EVENT("%s: Resizing Tx Queue Len to %li\n", + chan->if_name,dev->tx_queue_len); + chan->max_tx_bufs = dev->tx_queue_len; + } + + if (dev->tx_queue_len > chan->max_tx_bufs && + chan->max_tx_bufs != chan->max_tx_bufs_orig) { + DEBUG_EVENT("%s: Resizing Tx Queue Len to %i\n", + chan->if_name,chan->max_tx_bufs_orig); + chan->max_tx_bufs = chan->max_tx_bufs_orig; + } +#endif + +if_send_exit_crit: + + return err; +} + + +/*============================================================================ + * if_stats + * + * Used by /proc/net/dev and ifconfig to obtain interface + * statistics. + * + * Return a pointer to struct net_device_stats. + */ +static struct net_device_stats gstats; +static struct net_device_stats* if_stats (netdevice_t* dev) +{ + private_area_t* chan; + sdla_t *card; + + if ((chan=wan_netif_priv(dev)) == NULL) + return &gstats; + + card=chan->card; + +#if !defined(AFT_IRQ_DEBUG) + if (card) { +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc && + !card->u.aft.rtp_len && + card->wandev.config_id != WANCONFIG_AFT_ANALOG && + chan->common.usedby == TDM_VOICE) { + chan->if_stats.rx_packets = card->wandev.stats.rx_packets; + chan->if_stats.tx_packets = card->wandev.stats.tx_packets; + } +#endif + } +#endif + + return &chan->if_stats; + +} + +/*======================================================================== + * + * if_do_ioctl - Ioctl handler for fr + * + * @dev: Device subject to ioctl + * @ifr: Interface request block from the user + * @cmd: Command that is being issued + * + * This function handles the ioctls that may be issued by the user + * to control or debug the protocol or hardware . + * + * It does both busy and security checks. + * This function is intended to be wrapped by callers who wish to + * add additional ioctl calls of their own. + * + * Used by: SNMP Mibs + * wanpipemon debugger + * + */ +static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) +{ + private_area_t* chan= (private_area_t*)wan_netif_priv(dev); + sdla_t *card; +#if defined(__LINUX__) + wan_smp_flag_t smp_flags; +#endif + wan_udp_pkt_t *wan_udp_pkt; + int err=-EOPNOTSUPP; + + if (!chan || !chan->card){ + DEBUG_EVENT("%s:%d: No Chan of card ptr\n", + __FUNCTION__,__LINE__); + return -ENODEV; + } + card=chan->card; + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + DEBUG_EVENT("%s: Card down: Ignoring Ioctl call!\n", + card->devname); + return -ENODEV; + } + + switch(cmd) + { +#if defined(__LINUX__) + case SIOC_WANPIPE_BIND_SK: + if (!ifr){ + err= -EINVAL; + break; + } + + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + err=wan_bind_api_to_svc(chan,ifr->ifr_data); + chan->if_stats.rx_dropped=0; + if (!chan->hdlc_eng){ + chan->if_stats.tx_carrier_errors=0; + } + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + break; + + case SIOC_WANPIPE_UNBIND_SK: + if (!ifr){ + err= -EINVAL; + break; + } + + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + err=wan_unbind_api_from_svc(chan,ifr->ifr_data); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + + break; + + case SIOC_WANPIPE_CHECK_TX: + case SIOC_ANNEXG_CHECK_TX: + err=0; + break; + + case SIOC_WANPIPE_DEV_STATE: + err = chan->common.state; + break; + + case SIOC_ANNEXG_KICK: + err=0; + break; + + case SIOC_AFT_SS7_FORCE_RX: + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + aft_set_ss7_force_rx(card,chan); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + break; +#endif + +#if defined(AFT_API_SUPPORT) + case SIOC_WANPIPE_API: + DEBUG_TEST("%s: WANPIPE API IOCTL!\n", card->devname); + err = wan_aft_api_ioctl(card,chan,ifr->ifr_data); + break; +#endif + + case SIOC_WAN_DEVEL_IOCTL: + err = aft_devel_ioctl(card, ifr); + break; + + case SIOC_AFT_CUSTOMER_ID: + if (!ifr){ + return -EINVAL; + } else { + unsigned char cid=0; + wan_smp_flag_t smp_flags1; + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + cid=aft_read_cpld(card,CUSTOMER_CPLD_ID_REG); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + return WAN_COPY_TO_USER(ifr->ifr_data,&cid,sizeof(unsigned char)); + } + err=0; + break; + +#if defined(__LINUX__) + case SIOC_WANPIPE_GET_DEVICE_CONFIG_ID: + err=card->wandev.config_id; + break; +#endif + case SIOC_WANPIPE_SNMP: + case SIOC_WANPIPE_SNMP_IFSPEED: + return wan_snmp_data(card, dev, cmd, ifr); + + case SIOC_WANPIPE_PIPEMON: + + NET_ADMIN_CHECK(); + + if (wan_atomic_read(&chan->udp_pkt_len) != 0){ + return -EBUSY; + } + + wan_atomic_set(&chan->udp_pkt_len,MAX_LGTH_UDP_MGNT_PKT); + + /* For performance reasons test the critical + * here before spin lock */ + if (wan_test_bit(0,&card->in_isr)){ + wan_atomic_set(&chan->udp_pkt_len,0); + return -EBUSY; + } + + + wan_udp_pkt=(wan_udp_pkt_t*)chan->udp_pkt_data; + if (WAN_COPY_FROM_USER( + &wan_udp_pkt->wan_udp_hdr, + ifr->ifr_data, + sizeof(wan_udp_hdr_t))){ + wan_atomic_set(&chan->udp_pkt_len,0); + return -EFAULT; + } + + /* We have to check here again because we don't know + * what happened during spin_lock */ + if (wan_test_bit(0,&card->in_isr)) { + DEBUG_EVENT( "%s:%s Pipemon command failed, Driver busy: try again.\n", + card->devname, + wan_netif_name(dev)); + wan_atomic_set(&chan->udp_pkt_len,0); + return -EBUSY; + } + + process_udp_mgmt_pkt(card,dev,chan,1); + + /* This area will still be critical to other + * PIPEMON commands due to udp_pkt_len + * thus we can release the irq */ + + if (wan_atomic_read(&chan->udp_pkt_len) > sizeof(wan_udp_pkt_t)){ + DEBUG_EVENT( "%s: Error: Pipemon buf too bit on the way up! %d\n", + card->devname,wan_atomic_read(&chan->udp_pkt_len)); + wan_atomic_set(&chan->udp_pkt_len,0); + return -EINVAL; + } + + if (WAN_COPY_TO_USER( + ifr->ifr_data, + &wan_udp_pkt->wan_udp_hdr, + sizeof(wan_udp_hdr_t))){ + wan_atomic_set(&chan->udp_pkt_len,0); + return -EFAULT; + } + + wan_atomic_set(&chan->udp_pkt_len,0); + return 0; + +#if 0 + case SIOC_WAN_EC_IOCTL: + if (wan_test_and_set_bit(CARD_HW_EC,&card->wandev.critical)){ + DEBUG_EVENT("%s: Error: EC IOCTL Reentrant!\n", + card->devname); + return -EBUSY; + } + if (card->wandev.ec){ + err = wan_ec_ioctl(card->wandev.ec, ifr, card); + }else{ + err = -EINVAL; + } + wan_clear_bit(CARD_HW_EC,&card->wandev.critical); + break; +#endif + +/* + case SIOC_WAN_FE_IOCTL: + DEBUG_TEST("%s: Command %x not supported!\n", + card->devname,cmd); + return -EOPNOTSUPP; + break; +*/ + default: +#ifndef WANPIPE_GENERIC + DEBUG_TEST("%s: Command %x not supported!\n", + card->devname,cmd); + return -EOPNOTSUPP; +#else + if (card->wandev.ioctl){ + err = card->wandev.hdlc_ioctl(card, dev, ifr, cmd); + } +#endif + } + + return err; +} + + +/**SECTION********************************************************** + * + * FIRMWARE Specific Interface Functions + * + *******************************************************************/ + + +#define FIFO_RESET_TIMEOUT_CNT 1000 +#define FIFO_RESET_TIMEOUT_US 10 +static int aft_init_rx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char wait) +{ + + u32 reg; + u32 dma_descr; + u8 timeout=1; + u16 i; + unsigned int cur_dma_ptr; + u32 dma_ram_desc; + + /* Clean RX DMA fifo */ + + if (chan->single_dma_chain){ + dma_descr=(chan->logic_ch_num<<4) + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + aft_dmachain_set_rx_dma_addr(®,0); + card->hw_iface.bus_write_4(card->hw,dma_ram_desc,reg); + }else{ + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + + dma_descr=(chan->logic_ch_num<<4) + (cur_dma_ptr*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + } + + reg=0; + wan_set_bit(AFT_RXDMA_HI_DMA_CMD_BIT,®); + + DEBUG_TEST("%s: Clearing RX Fifo %s Ch=%ld DmaDescr=(0x%X) Reg=(0x%X)\n", + __FUNCTION__,chan->if_name,chan->logic_ch_num, + dma_descr,reg); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + if (wait == WP_WAIT){ + for(i=0;ihw_iface.bus_read_4(card->hw,dma_descr,®); + if (wan_test_bit(AFT_RXDMA_HI_DMA_CMD_BIT,®)){ + WP_DELAY(FIFO_RESET_TIMEOUT_US); + continue; + } + timeout=0; + break; + } + + if (timeout){ + DEBUG_EVENT("%s:%s: Error: Rx fifo reset timedout %u us\n", + card->devname,chan->if_name,i*FIFO_RESET_TIMEOUT_US); + }else{ + DEBUG_TEST("%s:%s: Rx Fifo Reset Successful\n", + card->devname,chan->if_name); + } + }else{ + timeout=0; + } + + return timeout; +} + +static int aft_init_tx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char wait) +{ + u32 reg; + u32 dma_descr,dma_ram_desc; + u8 timeout=1; + u16 i; + unsigned int cur_dma_ptr; + + if (chan->single_dma_chain){ + dma_descr=(chan->logic_ch_num<<4) + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + aft_dmachain_set_tx_dma_addr(®,0); + card->hw_iface.bus_write_4(card->hw,dma_ram_desc,reg); + }else{ + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_tx_dma_addr(reg); + + /* Clean TX DMA fifo */ + dma_descr=(chan->logic_ch_num<<4) + (cur_dma_ptr*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + } + + reg=0; + wan_set_bit(AFT_TXDMA_HI_DMA_CMD_BIT,®); + + DEBUG_TEST("%s: Clearing TX Fifo %s DmaDescr=(0x%X) Reg=(0x%X)\n", + __FUNCTION__,chan->if_name, + dma_descr,reg); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + if (wait == WP_WAIT){ + for(i=0;ihw_iface.bus_read_4(card->hw,dma_descr,®); + if (wan_test_bit(AFT_TXDMA_HI_DMA_CMD_BIT,®)){ + WP_DELAY(FIFO_RESET_TIMEOUT_US); + continue; + } + timeout=0; + break; + } + + if (timeout){ + DEBUG_EVENT("%s:%s: Error: Tx fifo reset timedout %u us\n", + card->devname,chan->if_name,i*FIFO_RESET_TIMEOUT_US); + }else{ + DEBUG_TEST("%s:%s: Tx Fifo Reset Successful\n", + card->devname,chan->if_name); + } + }else{ + timeout=0; + } + + return timeout; +} + +static void aft_channel_txdma_ctrl(sdla_t *card, private_area_t *chan, int on) +{ + u32 reg; + /* Enable TX DMA for Logic Channel */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_CTRL_REG), ®); + if (on){ + wan_set_bit(chan->logic_ch_num,®); + }else{ + wan_clear_bit(chan->logic_ch_num,®); + } + + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_CTRL_REG), reg); + +} +static void aft_channel_rxdma_ctrl(sdla_t *card, private_area_t *chan, int on) +{ + u32 reg; + /* Enable TX DMA for Logic Channel */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_CTRL_REG), ®); + if (on){ + wan_set_bit(chan->logic_ch_num,®); + }else{ + wan_clear_bit(chan->logic_ch_num,®); + } + + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_CTRL_REG), reg); + +} + +static void aft_channel_txintr_ctrl(sdla_t *card, private_area_t *chan, int on) +{ + u32 reg; + + /* Enable Logic Channel TX Interrupts */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_INTR_MASK_REG), ®); + if (on){ + wan_set_bit(chan->logic_ch_num,®); + }else{ + wan_clear_bit(chan->logic_ch_num,®); + + } + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_INTR_MASK_REG), reg); +} + +static void aft_channel_rxintr_ctrl(sdla_t *card, private_area_t *chan, int on) +{ + u32 reg; + + /* Enable Logic Channel TX Interrupts */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_INTR_MASK_REG), ®); + if (on){ + wan_set_bit(chan->logic_ch_num,®); + }else{ + wan_clear_bit(chan->logic_ch_num,®); + + } + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_INTR_MASK_REG), reg); +} + + +static void aft_dev_enable(sdla_t *card, private_area_t *chan) +{ + DEBUG_TEST("%s: Enabling Global Inter Mask !\n",chan->if_name); + + /* Enable TX DMA for Logic Channel */ + aft_channel_txdma_ctrl(card,chan,1); + + /* Enable RX DMA for Logic Channel */ + aft_channel_rxdma_ctrl(card,chan,1); + + /* Enable Logic Channel TX Interrupts */ + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_channel_txintr_ctrl(card,chan,0); + aft_channel_rxintr_ctrl(card,chan,0); + chan->tdmv_irq_cfg=1; + }else{ + aft_channel_txintr_ctrl(card,chan,1); + aft_channel_rxintr_ctrl(card,chan,1); + } + + wan_set_bit(chan->logic_ch_num,&card->u.aft.active_ch_map); +} + +static void aft_dev_open_private(sdla_t *card, private_area_t *chan) +{ + if (card->wandev.state == WAN_CONNECTED && + wan_test_bit(0,&card->u.aft.comm_enabled)){ + + DEBUG_TEST("%s: OPEN reseting fifo\n", + chan->if_name); + + aft_tslot_sync_ctrl(card,chan,0); + + aft_init_rx_dev_fifo(card,chan,WP_NO_WAIT); + aft_init_tx_dev_fifo(card,chan,WP_NO_WAIT); + + aft_dev_enable(card,chan); + + aft_init_rx_dev_fifo(card,chan,WP_WAIT); + aft_init_tx_dev_fifo(card,chan,WP_WAIT); + + chan->dma_index=0; + memset(chan->dma_history,0,sizeof(chan->dma_history)); + + aft_reset_rx_chain_cnt(chan); + aft_dma_rx(card,chan); + + aft_tslot_sync_ctrl(card,chan,1); + + if (!chan->hdlc_eng){ + aft_reset_tx_chain_cnt(chan); + aft_dma_tx(card,chan); + } + }else{ + aft_dev_enable(card,chan); + } + +} + +static void aft_dev_open(sdla_t *card, private_area_t *gchan) +{ + private_area_t *chan=gchan; + + if (chan->channelized_cfg){ + + for (chan=gchan; chan != NULL; chan=chan->next){ + + aft_dev_open_private(card,chan); + + wan_set_bit(0,&chan->up); + + } + + if (gchan->common.usedby == TDM_VOICE_API){ + /* Set the global mtu value which is + * the sum of all timeslots mtus */ + wan_netif_set_mtu( + gchan->common.dev, + card->u.aft.tdmv_mtu+sizeof(api_tx_hdr_t)); + + } + + wan_set_bit(0,&card->u.aft.tdmv_master_if_up); + + if (card->wandev.state == WAN_CONNECTED && + !wan_test_bit(0,&card->u.aft.comm_enabled)){ + DEBUG_EVENT("%s: Master IF Starting %s Communications\n", + gchan->if_name,card->devname); + enable_data_error_intr(card); + } + }else{ + aft_dev_open_private(card,chan); + wan_set_bit(0,&chan->up); + } + + + if (gchan->cfg.ss7_enable){ + aft_clear_ss7_force_rx(card,gchan); + } + + return; +} + +static void aft_dev_close_private(sdla_t *card, private_area_t *chan) +{ + + if (chan->logic_ch_num < 0){ + return; + } + + /* Disable Logic Channel TX Interrupts */ + aft_channel_txintr_ctrl(card,chan,0); + + /* Disable Logic Channel RX Interrupts */ + aft_channel_rxintr_ctrl(card,chan,0); + + /* Disable TX DMA for Logic Channel */ + aft_channel_txdma_ctrl(card,chan,0); + + /* Disable RX DMA for Logic Channel */ + aft_channel_rxdma_ctrl(card,chan,0); + + /* Initialize DMA descriptors and DMA Chains */ + aft_init_tx_rx_dma_descr(chan); + +} + + +static void aft_dev_close(sdla_t *card, private_area_t *gchan) +{ + private_area_t *chan=gchan; + + if (chan->channelized_cfg){ + + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); + + for (chan=gchan; chan != NULL; chan=chan->next){ + + aft_dev_close_private(card,chan); + + DEBUG_TEST("%s: Closing Ch=%ld\n", + chan->if_name,chan->logic_ch_num); + + wan_clear_bit(0,&chan->up); + wan_set_bit(0,&chan->interface_down); + if (chan->cfg.tdmv_master_if){ + wan_clear_bit(0,&card->u.aft.tdmv_master_if_up); + } + } + }else{ + wan_set_bit(0,&chan->interface_down); + wan_clear_bit(0,&chan->up); + aft_dev_close_private(card,chan); + + + } + return; +} + +/**SECTION************************************************************* + * + * TX Handlers + * + **********************************************************************/ + + +/*=============================================== + * aft_dma_tx_complete + * + */ +static void aft_dma_tx_complete (sdla_t *card, private_area_t *chan, int wdt, int reset) +{ + DEBUG_TEST("%s: Tx interrupt wdt=%d\n",chan->if_name,wdt); + + if (!wdt){ + wan_clear_bit(TX_INTR_PENDING,&chan->dma_chain_status); + } + + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_tx_dma_voice_handler((unsigned long)chan,wdt,reset); + }else{ + aft_tx_dma_chain_handler((unsigned long)chan,wdt,reset); + } + + wan_set_bit(0,&chan->idle_start); + + if (reset){ + return; + } + + aft_dma_tx(card,chan); + + if (WAN_NETIF_QUEUE_STOPPED(chan->common.dev)){ + WAN_NETIF_WAKE_QUEUE(chan->common.dev); +#ifndef CONFIG_PRODUCT_WANPIPE_GENERIC + if (chan->common.usedby == API){ + wan_wakeup_api(chan); + }else if (chan->common.usedby == STACK){ + wanpipe_lip_kick(chan,0); + } +#endif + } + + if (chan->common.usedby == TDM_VOICE_DCHAN){ +#ifdef AFT_TDM_API_SUPPORT + if (is_tdm_api(chan,&chan->wp_tdm_api_dev)){ + wanpipe_tdm_api_kick(&chan->wp_tdm_api_dev); + } +#endif + } + + return; +} + +/*=============================================== + * aft_tx_post_complete + * + */ +static void aft_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_t *skb) +{ + unsigned int reg = wan_skb_csum(skb); + u32 dma_status = aft_txdma_hi_get_dma_status(reg); + + wan_skb_set_csum(skb,0); + + if (reg & AFT_TXDMA_HI_DMA_LENGTH_MASK){ + chan->errstats.Tx_dma_len_nonzero++; + } + + if ((wan_test_bit(AFT_TXDMA_HI_GO_BIT,®)) || + (reg & AFT_TXDMA_HI_DMA_LENGTH_MASK) || + dma_status){ + + DEBUG_TEST("%s:%s: Tx DMA Descriptor=0x%X\n", + card->devname,chan->if_name,reg); + + /* Checking Tx DMA Go bit. Has to be '0' */ + if (wan_test_bit(AFT_TXDMA_HI_GO_BIT,®)){ + DEBUG_TEST("%s:%s: Error: TxDMA Intr: GO bit set on Tx intr\n", + card->devname,chan->if_name); + chan->errstats.Tx_dma_errors++; + } + + if (reg & AFT_TXDMA_HI_DMA_LENGTH_MASK){ + DEBUG_EVENT("%s:%s: Error: TxDMA Length not equal 0 (reg=0x%08X)\n", + card->devname,chan->if_name,reg); + chan->errstats.Tx_dma_errors++; + } + + /* Checking Tx DMA PCI error status. Has to be '0's */ + if (dma_status){ + + chan->errstats.Tx_pci_errors++; + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_M_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: Abort from Master: pci fatal error!\n", + card->devname,chan->if_name); + } + + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_T_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: Abort from Target: pci fatal error!\n", + card->devname,chan->if_name); + } + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_DS_TOUT,&dma_status)){ + DEBUG_TEST("%s:%s: Tx Warning: PCI Latency Timeout!\n", + card->devname,chan->if_name); + chan->errstats.Tx_pci_latency++; + goto tx_post_ok; + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_RETRY,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: 'Retry' exceeds maximum (64k): pci fatal error!\n", + card->devname,chan->if_name); + } + } + } + chan->if_stats.tx_errors++; + goto tx_post_exit; + } + +tx_post_ok: + + chan->opstats.Data_frames_Tx_count++; + chan->opstats.Data_bytes_Tx_count+=wan_skb_len(skb); + chan->if_stats.tx_packets++; + chan->if_stats.tx_bytes+=wan_skb_len(skb); + +#if 0 + if (chan->common.usedby != TDM_VOICE){ + wan_capture_trace_packet(card, &chan->trace_info, skb, TRC_OUTGOING_FRM); + } +#endif + +tx_post_exit: + + return; +} + + + +/**SECTION************************************************************* + * + * RX Handlers + * + **********************************************************************/ + + +/*=============================================== + * aft_rx_post_complete + * + */ +static void aft_rx_post_complete (sdla_t *card, private_area_t *chan, + netskb_t *skb, + netskb_t **new_skb, + unsigned char *pkt_error) +{ + + unsigned int len,data_error = 0; + unsigned char *buf; + wp_rx_element_t *rx_el; + u32 dma_status; + rx_el=(wp_rx_element_t *)wan_skb_data(skb); + + DEBUG_RX("%s:%s: RX HI=0x%X LO=0x%X\n DMA=0x%X", + __FUNCTION__, + chan->if_name, + rx_el->reg, + rx_el->align, + rx_el->dma_addr); + +#if 0 + /* debugging */ + chan->if_stats.rx_errors++; +#endif + + rx_el->align&=AFT_RXDMA_LO_ALIGN_MASK; + *pkt_error=0; + *new_skb=NULL; + + dma_status=aft_rxdma_hi_get_dma_status(rx_el->reg); + + /* Checking Rx DMA Go bit. Has to be '0' */ + if (wan_test_bit(AFT_RXDMA_HI_GO_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: Error: RxDMA Intr: GO bit set on Rx intr\n", + card->devname,chan->if_name); + chan->if_stats.rx_errors++; + chan->errstats.Rx_dma_descr_err++; + goto rx_comp_error; + } + + /* Checking Rx DMA PCI error status. Has to be '0's */ + if (dma_status){ + + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_M_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: Abort from Master: pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_T_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: Abort from Target: pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_DS_TOUT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: No 'DeviceSelect' from target: pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_RETRY,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: 'Retry' exceeds maximum (64k): pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + + chan->errstats.Rx_pci_errors++; + chan->if_stats.rx_errors++; + card->wandev.stats.rx_errors++; + goto rx_comp_error; + } + + if (chan->hdlc_eng){ + + /* Checking Rx DMA Frame start bit. (information for api) */ + if (!wan_test_bit(AFT_RXDMA_HI_START_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s RxDMA Intr: Start flag missing: MTU Mismatch! Reg=0x%X\n", + card->devname,chan->if_name,rx_el->reg); + chan->if_stats.rx_frame_errors++; + chan->opstats.Rx_Data_discard_long_count++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_errors++; + goto rx_comp_error; + } + + /* Checking Rx DMA Frame end bit. (information for api) */ + if (!wan_test_bit(AFT_RXDMA_HI_EOF_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: RxDMA Intr: End flag missing: MTU Mismatch! Reg=0x%X\n", + card->devname,chan->if_name,rx_el->reg); + chan->if_stats.rx_frame_errors++; + chan->opstats.Rx_Data_discard_long_count++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_errors++; + goto rx_comp_error; + + } else { /* Check CRC error flag only if this is the end of Frame */ + + if (wan_test_bit(AFT_RXDMA_HI_FCS_ERR_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: RxDMA Intr: CRC Error! Reg=0x%X Len=%d\n", + card->devname,chan->if_name,rx_el->reg, + (rx_el->reg&AFT_RXDMA_HI_DMA_LENGTH_MASK)>>2); + chan->if_stats.rx_frame_errors++; + chan->errstats.Rx_crc_err_count++; + card->wandev.stats.rx_crc_errors++; + wan_set_bit(WP_CRC_ERROR_BIT,&rx_el->pkt_error); + data_error = 1; + } + + /* Check if this frame is an abort, if it is + * drop it and continue receiving */ + if (wan_test_bit(AFT_RXDMA_HI_FRM_ABORT_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: RxDMA Intr: Abort! Reg=0x%X\n", + card->devname,chan->if_name,rx_el->reg); + chan->if_stats.rx_frame_errors++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_frame_errors++; + wan_set_bit(WP_ABORT_ERROR_BIT,&rx_el->pkt_error); + data_error = 1; + } + + if (chan->common.usedby != API && data_error){ + goto rx_comp_error; + } + + } + } + + len=rx_el->reg&AFT_RXDMA_HI_DMA_LENGTH_MASK; + + if (chan->hdlc_eng){ + /* In HDLC mode, calculate rx length based + * on alignment value, received from DMA */ + len=((((chan->dma_mru>>2)-1)-len)<<2) - (~(rx_el->align)&AFT_RXDMA_LO_ALIGN_MASK); + + if (len < 3 || len > chan->dma_mru){ + chan->if_stats.rx_frame_errors++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_frame_errors++; + goto rx_comp_error; + } + }else{ + /* In Transparent mode, our RX buffer will always be + * aligned to the 32bit (word) boundary, because + * the RX buffers are all of equal length */ + len=(((chan->mru>>2)-len)<<2) - (~(0x03)&AFT_RXDMA_LO_ALIGN_MASK); + + if (len < 1 || len > chan->mru){ + chan->if_stats.rx_frame_errors++; + card->wandev.stats.rx_frame_errors++; + goto rx_comp_error; + } + } + + + + *pkt_error=rx_el->pkt_error; + + /* After a RX FIFO overflow, we must mark max 7 + * subsequent frames since firmware, cannot + * guarantee the contents of the fifo */ + + if (wan_test_bit(WP_FIFO_ERROR_BIT,&rx_el->pkt_error)){ + if (chan->hdlc_eng){ + if (++chan->rx_fifo_err_cnt >= WP_MAX_FIFO_FRAMES){ + chan->rx_fifo_err_cnt=0; + } + }else{ + chan->rx_fifo_err_cnt=0; + } + wan_set_bit(WP_FIFO_ERROR_BIT,pkt_error); + }else{ + if (chan->rx_fifo_err_cnt){ + if (++chan->rx_fifo_err_cnt >= WP_MAX_FIFO_FRAMES){ + chan->rx_fifo_err_cnt=0; + } + wan_set_bit(WP_FIFO_ERROR_BIT,pkt_error); + } + } + + + if (len > aft_rx_copyback){ + /* The rx size is big enough, thus + * send this buffer up the stack + * and allocate another one */ + memset(wan_skb_data(skb),0,sizeof(wp_rx_element_t)); + wan_skb_put(skb,len); + wan_skb_pull(skb, sizeof(wp_rx_element_t)); + *new_skb=skb; + + aft_alloc_rx_dma_buff(card,chan,1,1); + }else{ + + /* The rx packet is very + * small thus, allocate a new + * buffer and pass it up */ + *new_skb=wan_skb_alloc(len + 20); + if (!*new_skb){ + DEBUG_EVENT("%s:%s: Failed to allocate rx skb pkt (len=%d)!\n", + card->devname,chan->if_name,(len+20)); + chan->if_stats.rx_dropped++; + goto rx_comp_error; + } + + buf=wan_skb_put((*new_skb),len); + memcpy(buf,wan_skb_tail(skb),len); + + aft_init_requeue_free_skb(chan, skb); + } + +#if 0 + if (chan->hdlc_eng){ + buf=wan_skb_data(*new_skb); + if (buf[wan_skb_len(*new_skb)-1] != 0x7E && + buf[wan_skb_len(*new_skb)-1] != 0x7F){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Rx: Invalid packet len=%d: 0x%X 0x%X 0x%X\n", + card->devname, + wan_skb_len(*new_skb), + buf[wan_skb_len(*new_skb)-3], + buf[wan_skb_len(*new_skb)-2], + buf[wan_skb_len(*new_skb)-1]); + } + } + } +#endif + + return; + +rx_comp_error: + + aft_init_requeue_free_skb(chan, skb); + return; +} + + + +/**SECTION************************************************** + * + * Logic Channel Registration Support and + * Utility funcitons + * + **********************************************************/ + +static int aft_init_requeue_free_skb(private_area_t *chan, netskb_t *skb) +{ + WAN_ASSERT(skb == NULL); + + wan_skb_init(skb,16); + wan_skb_trim(skb,0); + wan_skb_queue_tail(&chan->wp_rx_free_list,skb); + + return 0; +} + +static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num, int irq) +{ + int i; + netskb_t *skb; + + for (i=0;ichannelized_cfg && !chan->hdlc_eng){ +#if defined(WANPIPE_64BIT_4G_DMA) +#warning "Wanpipe compiled for 64bit 4G DMA" + /* On 64bit Systems greater than 4GB we must + * allocated our DMA buffers using GFP_DMA + * flag */ + if (irq) { + skb=__dev_alloc_skb(chan->dma_mru,GFP_DMA|GFP_ATOMIC); + } else { + skb=__dev_alloc_skb(chan->dma_mru,GFP_DMA|GFP_KERNEL); + } +#else + if (irq) { + skb=wan_skb_alloc(chan->dma_mru); + } else { + skb=wan_skb_kalloc(chan->dma_mru); + } +#endif + } else { + if (irq) { + skb=wan_skb_alloc(chan->dma_mru); + } else { + skb=wan_skb_kalloc(chan->dma_mru); + } + } + if (!skb){ + DEBUG_EVENT("%s: %s no rx memory\n", + chan->if_name,__FUNCTION__); + return -ENOMEM; + } + wan_skb_queue_tail(&chan->wp_rx_free_list,skb); + } + + + + return 0; +} + + +/*============================================================================ + * Enable timer interrupt + */ +static void enable_timer (void* card_id) +{ + sdla_t* card = (sdla_t*)card_id; +#if !defined(WAN_IS_TASKQ_SCHEDULE) + wan_smp_flag_t smp_flags; + wan_smp_flag_t smp_flags1; + int err = 0; +#endif + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + DEBUG_EVENT("%s: Card down: Ignoring enable_timer!\n", + card->devname); + return; + } + + DEBUG_56K("%s: %s Sdla Polling %p!\n",__FUNCTION__, + card->devname, + card->wandev.fe_iface.polling); + +#if defined(WAN_IS_TASKQ_SCHEDULE) + wan_set_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); +#else + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + if (card->wandev.fe_iface.polling){ + err = card->wandev.fe_iface.polling(&card->fe); + } + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); +#endif + + return; +} + +static void enable_ec_timer (void* card_id) +{ +#if defined(CONFIG_WANPIPE_HWEC) + sdla_t* card = (sdla_t*)card_id; +# if !defined(WAN_IS_TASKQ_SCHEDULE) + wan_smp_flag_t smp_flags; + wan_smp_flag_t smp_flags1; +# endif + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + DEBUG_EVENT("%s: Card down: Ignoring enable_timer!\n", + card->devname); + return; + } + + DEBUG_TEST("%s: %s Sdla EC Polling !\n",__FUNCTION__, + card->devname); + +# if defined(WAN_IS_TASKQ_SCHEDULE) + wan_set_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); +# else +# error "TASK Q Not defined" + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + + wanpipe_ec_poll(card->wandev.ec_dev, card); + + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); +# endif +#endif + return; +} +/**SECTION************************************************** + * + * API Bottom Half Handlers + * + **********************************************************/ + +static int tdm_check=0; + +#if defined(__LINUX__) +static void wp_tdm_bh (unsigned long data) +#else +static void wp_tdm_bh (void *data, int pending) +#endif +{ +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + private_area_t* chan = (private_area_t *)data; + sdla_t *card=chan->card; + int err; + +#if 0 + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: TDM BH Running !\n", + chan->if_name); + } +#endif + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + goto wp_tdm_bh_exit; + } + + if (!wan_test_bit(0,&chan->up)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: wp_tdm_bh() chan not up!\n", + chan->if_name); + } + goto wp_tdm_bh_exit; + } + +#if 0 + if (tdm_check){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: TDM BH Already Running 0x%02X... cool!\n", + chan->if_name,tdm_check); + } + } + wan_set_bit(card->tdmv_conf.span_no,&tdm_check); +#endif + WAN_TDMV_CALL(rx_tx_span, (card), err); + + WAN_TASKLET_END((&chan->common.bh_task)); + + if (card->wan_tdmv.sc){ + WAN_TDMV_CALL(is_rbsbits, (&card->wan_tdmv), err); + if (err == 1){ + wan_set_bit(AFT_FE_TDM_RBS,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } + } + +#if 0 + wan_clear_bit(card->tdmv_conf.span_no,&tdm_check); +#endif + tdm_check++; + + return; + +wp_tdm_bh_exit: + WAN_TASKLET_END((&chan->common.bh_task)); +#endif + return; +} + + +#if defined(__LINUX__) +static void wp_bh (unsigned long data) +#else +static void wp_bh (void *data, int pending) +#endif +{ + private_area_t* chan = (private_area_t *)data; + sdla_t *card=chan->card; + netskb_t *new_skb,*skb; + unsigned char pkt_error; + unsigned long timeout=SYSTEM_TICKS; + private_area_t *top_chan; + int len; + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.collisions++; +#endif + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + WAN_TASKLET_END((&chan->common.bh_task)); + return; + } + + if (card->u.aft.tdmv_dchan){ + top_chan=wan_netif_priv(chan->common.dev); + }else{ + top_chan=chan; + } + + DEBUG_TEST("%s: ------------ BEGIN --------------: %u\n", + __FUNCTION__,SYSTEM_TICKS); + + if (!wan_test_bit(0,&chan->up)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: wp_bh() chan not up!\n", + chan->if_name); + } + WAN_TASKLET_END((&chan->common.bh_task)); + return; + } + + while((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ + +#if 0 + chan->if_stats.rx_errors++; +#endif + + if (SYSTEM_TICKS-timeout > 1){ + wan_skb_queue_head(&chan->wp_rx_complete_list,skb); + break; + } + + new_skb=NULL; + pkt_error=0; + + + + /* The post function will take care + * of the skb and new_skb buffer. + * If new_skb buffer exists, driver + * must pass it up the stack, or free it */ + aft_rx_post_complete (chan->card, chan, + skb, + &new_skb, + &pkt_error); + if (new_skb){ + + len=wan_skb_len(new_skb); + + if (chan->hdlc_eng){ + /* HDLC packets contain 2 byte crc and 1 byte + * flag. If data is not greater than 3, then + * we have a 0 length frame. Thus discard + * (only if HDLC engine enabled) */ + if (len <= 3){ + ++chan->if_stats.rx_errors; + wan_skb_free(new_skb); + continue; + } + + wan_skb_trim(new_skb,wan_skb_len(new_skb)-3); + len-=3; + } + + wan_capture_trace_packet(chan->card, &top_chan->trace_info, + new_skb,TRC_INCOMING_FRM); + + + if (chan->common.usedby == API){ + + if (chan->common.sk == NULL){ + DEBUG_TEST("%s: No sock bound to channel rx dropping!\n", + chan->if_name); + chan->if_stats.rx_dropped++; + wan_skb_free(new_skb); + continue; + } + + if (chan->hdlc_eng){ + if (card->u.aft.cfg.rx_crc_bytes == 3){ + wan_skb_put(new_skb,3); + }else if (card->u.aft.cfg.rx_crc_bytes == 2){ + wan_skb_put(new_skb,2); + } + } + +#if defined(__LINUX__) +# ifndef CONFIG_PRODUCT_WANPIPE_GENERIC + + + /* Only for API, we insert packet status + * byte to indicate a packet error. Take + * this byte and put it in the api header */ + + if (wan_skb_headroom(new_skb) >= sizeof(api_rx_hdr_t)){ + api_rx_hdr_t *rx_hdr= + (api_rx_hdr_t*)skb_push(new_skb,sizeof(api_rx_hdr_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + rx_hdr->error_flag=pkt_error; + }else{ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Error Rx pkt headroom %u < %u\n", + chan->if_name, + (u32)wan_skb_headroom(new_skb), + (u32)sizeof(api_rx_hdr_t)); + } + ++chan->if_stats.rx_dropped; + wan_skb_free(new_skb); + continue; + } + + new_skb->protocol = htons(PVC_PROT); + wan_skb_reset_mac_header(new_skb); + new_skb->dev = chan->common.dev; + new_skb->pkt_type = WAN_PACKET_DATA; + +#if 0 + chan->if_stats.rx_frame_errors++; +#endif + + if (wan_api_rx(chan,new_skb) != 0){ + ++chan->if_stats.rx_dropped; + wan_skb_free(new_skb); + continue; + } + +# endif +#endif + + }else if (chan->common.usedby == TDM_VOICE_DCHAN){ + +#ifdef AFT_TDM_API_SUPPORT + if (is_tdm_api(chan,&chan->wp_tdm_api_dev)) { + int err; + + if (wan_skb_headroom(new_skb) >= sizeof(api_rx_hdr_t)){ + api_rx_hdr_t *rx_hdr = + (api_rx_hdr_t*)skb_push(new_skb,sizeof(api_rx_hdr_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + //rx_hdr->error_flag=pkt_error; + }else{ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Error Rx pkt headroom %u < %u\n", + chan->if_name, + (u32)wan_skb_headroom(new_skb), + (u32)sizeof(api_rx_hdr_t)); + } + ++chan->if_stats.rx_dropped; + wan_skb_free(new_skb); + continue; + } + err=wanpipe_tdm_api_rx_hdlc(&chan->wp_tdm_api_dev,new_skb); + if (err){ + ++chan->if_stats.rx_dropped; + wan_skb_free(new_skb); + continue; + } + + }else +#endif + if (chan->tdmv_zaptel_cfg){ + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) + int err; +/* ADEBUG */ + WAN_TDMV_CALL(rx_dchan, + (&card->wan_tdmv,chan->tdmv_chan, + wan_skb_data(new_skb),wan_skb_len(new_skb)), + err); + + DEBUG_TEST("%s TDM DCHAN VOICE Rx Pkt Len=%i Chan=%i\n", + card->devname,wan_skb_len(new_skb), + chan->tdmv_chan); +#else + DEBUG_EVENT("%s: DCHAN Rx Packet critical error TDMV not compiled!\n",card->devname); +#endif + + wan_skb_free(new_skb); + /* Continue through since the above + * function returns void */ + + } else { + DEBUG_EVENT("%s: DCHAN Rx Packet critical error op not supported\n",card->devname); + ++chan->if_stats.rx_dropped; + wan_skb_free(new_skb); + continue; + } + + }else if (chan->common.usedby == TDM_VOICE){ + + DEBUG_EVENT("%s: TDM VOICE CRITICAL: IN BH!!!!\n",card->devname); + ++chan->if_stats.rx_dropped; + wan_skb_free(new_skb); + continue; + + }else if (chan->common.usedby == STACK){ + + wan_skb_set_csum(new_skb,0); + + if (wanpipe_lip_rx(chan,new_skb) != 0){ + ++chan->if_stats.rx_dropped; + wan_skb_free(new_skb); + continue; + } + + }else{ + protocol_recv(chan->card,chan,new_skb); + } + + chan->opstats.Data_frames_Rx_count++; + chan->opstats.Data_bytes_Rx_count+=len; + chan->if_stats.rx_packets++; + chan->if_stats.rx_bytes+=len; + } + + } + + while((skb=wan_skb_dequeue(&chan->wp_rx_stack_complete_list)) != NULL){ + len=wan_skb_len(skb); + if (wanpipe_lip_rx(chan,skb) != 0){ + ++chan->if_stats.rx_dropped; + wan_skb_free(skb); + }else{ + chan->opstats.Data_frames_Rx_count++; + chan->opstats.Data_bytes_Rx_count+=len; + chan->if_stats.rx_packets++; + chan->if_stats.rx_bytes+=len; + } + } + + while((skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ + aft_tx_post_complete (chan->card,chan,skb); + wan_skb_free(skb); + } + + + WAN_TASKLET_END((&chan->common.bh_task)); + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + WAN_TASKLET_END((&chan->common.bh_task)); + return; + } + +#if 1 + { + + if ((len=wan_skb_queue_len(&chan->wp_rx_complete_list))){ + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + }else if ((len=wan_skb_queue_len(&chan->wp_tx_complete_list))){ + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + }else if ((len=wan_skb_queue_len(&chan->wp_rx_stack_complete_list))){ + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + } + + } +#endif + + DEBUG_TEST("%s: ------------ END -----------------: %u\n", + __FUNCTION__,SYSTEM_TICKS); + + return; +} + +/**SECTION************************************************** + * + * Interrupt Support Functions + * + **********************************************************/ +static void wp_aft_fifo_per_port_isr(sdla_t *card) +{ + u32 rx_status, tx_status; + u32 i; + private_area_t *chan; + int num_of_logic_ch; + u32 tmp_fifo_reg; + + /* Clear HDLC pending registers */ + __sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG),&tx_status); + __sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG),&rx_status); + + tx_status&=card->u.aft.active_ch_map; + rx_status&=card->u.aft.active_ch_map; + + num_of_logic_ch=card->u.aft.num_of_time_slots; + + if (!wan_test_bit(0,&card->u.aft.comm_enabled)){ + if (tx_status){ + card->wandev.stats.tx_aborted_errors++; + } + if (rx_status){ + card->wandev.stats.rx_over_errors++; + } + return; + } + + if (tx_status != 0){ + for (i=0;iu.aft.logic_ch_map)){ + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + DEBUG_EVENT("Warning: ignoring tx fifo intr: no dev!\n"); + continue; + } + + if (wan_test_bit(0,&chan->interface_down)){ + continue; + } +#if 1 + if (!chan->hdlc_eng && !wan_test_bit(0,&chan->idle_start)){ + DEBUG_TEST("%s: Warning: ignoring tx fifo: dev idle start!\n", + chan->if_name); + continue; + } +#endif + DEBUG_TEST("%s:%s: Warning TX Fifo Error on LogicCh=%ld Slot=%d!\n", + card->devname,chan->if_name,chan->logic_ch_num,i); + +#if 0 +{ + u32 dma_descr,tmp_reg; + dma_descr=(chan->logic_ch_num<<4) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + + card->hw_iface.bus_read_4(card->hw,dma_descr, &tmp_reg); + + DEBUG_EVENT("%s:%s: Warning TX Fifo Error on LogicCh=%ld Slot=%d Reg=0x%X!\n", + card->devname,chan->if_name,chan->logic_ch_num,i,tmp_reg); + +#if 1 + aft_list_tx_descriptors(chan); + aft_critical_shutdown(card); + break; + +#endif + +} +#endif + + aft_tx_fifo_under_recover(card,chan); + ++chan->if_stats.tx_fifo_errors; + card->wandev.stats.tx_aborted_errors++; + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG),&tmp_fifo_reg); + } + } + } + + + if (rx_status != 0){ + for (i=0;iu.aft.logic_ch_map)){ + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (wan_test_bit(0,&chan->interface_down)){ + continue; + } + +#ifdef AFT_RX_FIFO_DEBUG +{ + u32 dma_descr,tmp1_reg,tmp_reg,cur_dma_ptr; + u32 dma_ram_desc=chan->logic_ch_num*4 + + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,&tmp_reg); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(tmp_reg); + + dma_descr=(chan->logic_ch_num<<4) + cur_dma_ptr*AFT_DMA_INDEX_OFFSET + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr, &tmp_reg); + card->hw_iface.bus_read_4(card->hw,(dma_descr-4), &tmp1_reg); + + + if (wan_test_bit(AFT_RXDMA_HI_GO_BIT,&tmp_reg)){ + DEBUG_EVENT("%s: Rx Fifo Go Bit Set DMA=%d Addr=0x%X : HI=0x%08X LO=0x%08X OLO=0x%08X Cfg=0x%08X!\n", + card->devname, + cur_dma_ptr, + dma_descr, + tmp_reg,tmp1_reg, +chan->rx_dma_chain_table[chan->rx_chain_indx].dma_addr, +0); + } + + DEBUG_EVENT("%s:%s: Warning RX Fifo Error on Ch=%ld End=%d Cur=%d: Reg=0x%X Addr=0x%X!\n", + card->devname,chan->if_name,chan->logic_ch_num, + chan->rx_chain_indx,cur_dma_ptr,tmp_reg,dma_descr); + +} +#if 0 + aft_display_chain_history(chan); + aft_list_descriptors(chan); +#endif +#endif + ++chan->if_stats.rx_fifo_errors; + ++chan->if_stats.rx_over_errors; + chan->errstats.Rx_overrun_err_count++; + card->wandev.stats.rx_over_errors++; + + aft_rx_fifo_over_recover(card,chan); + wan_set_bit(WP_FIFO_ERROR_BIT, &chan->pkt_error); + + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG),&tmp_fifo_reg); +#if 0 + /* Debuging Code used to stop the line in + * case of fifo errors */ + aft_list_descriptors(chan); + + aft_critical_shutdown(card); +#endif + } + } + } + + return; +} + + +static void front_end_interrupt(sdla_t *card, unsigned long reg, int lock) +{ + if (card->wandev.fe_iface.isr){ + card->wandev.fe_iface.isr(&card->fe); + + if (lock){ + wan_smp_flag_t smp_flags; + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + }else{ + handle_front_end_state(card); + } + } + return; +} +/**SECTION*************************************************************** + * + * HARDWARE Interrupt Handlers + * + ***********************************************************************/ + + +/*============================================================================ + * wpfw_isr + * + * Main interrupt service routine. + * Determin the interrupt received and handle it. + * + */ +#if 0 +static u32 aft_shared_irq=0; +static u32 aft_master_dev=0xF; +#endif +#if 0 +static int gdma_cnt=0; +#endif + +#define EC_IRQ_TIMEOUT (HZ) + +static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) +{ + u32 reg_sec=0,reg=0; + u32 a108_reg=0, a56k_reg=0; + u32 fifo_port_intr=0; + u32 dma_port_intr=0; + u32 wdt_port_intr=0; + u32 tdmv_port_intr=0; + u32 fe_intr=0; + + WAN_IRQ_RETVAL_DECL(irq_ret); + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + DEBUG_TEST("%s: Card down, ignoring interrupt!!!!!!!\n", + card->devname); + WAN_IRQ_RETURN(irq_ret); + } + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_errors++; +#endif + + if (tdm_check > 0){ + card->wandev.stats.rx_errors=tdm_check; + } + +#ifdef AFT_IRQ_DEBUG + card->wandev.stats.rx_packets++; + if (SYSTEM_TICKS-card->u.aft.gtimeout >= HZ){ + card->wandev.stats.tx_packets=card->wandev.stats.rx_packets; + card->wandev.stats.rx_packets=0; + card->u.aft.gtimeout=SYSTEM_TICKS; + } +#endif + + wan_set_bit(0,&card->in_isr); + + /* -----------------2/6/2003 9:02AM------------------ + * Disable all chip Interrupts (offset 0x040) + * -- "Transmit/Receive DMA Engine" interrupt disable + * -- "FiFo/Line Abort Error" interrupt disable + * --------------------------------------------------*/ + __sdla_bus_read_4(card->hw,AFT_CHIP_CFG_REG, ®); + reg_sec=reg; + + if (wan_test_bit(AFT_CHIPCFG_FE_INTR_STAT_BIT,®)){ + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_dropped++; +#endif + + if (wan_test_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®)) { + + DEBUG_TEST("%s: Got Front End Interrupt 0x%08X\n", + card->devname,reg); + + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.tx_dropped++; +#endif + + fe_intr=1; + /*FIXME: Give Alex the reg to acknowledge remoras */ + if (card->wandev.fe_iface.check_isr && + card->wandev.fe_iface.check_isr(&card->fe)){ +#if defined(__LINUX__) + wan_set_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + __aft_fe_intr_ctrl(card,0); +#else + front_end_interrupt(card,reg,0); +#endif + } + } + } + +/* New Octasic implementarion May 16 2006 */ +#if defined(CONFIG_WANPIPE_HWEC) + if (card->wandev.ec_dev && + SYSTEM_TICKS-card->wandev.ec_intmask > EC_IRQ_TIMEOUT) { + card->wandev.ec_intmask=SYSTEM_TICKS; + if (!wan_test_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd)){ + /* All work is done from ec_poll routine!!! */ + wan_set_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } + } +#endif + + if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID) { + + __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &a108_reg); + fifo_port_intr = aft_chipcfg_a108_get_fifo_intr_stats(a108_reg); + dma_port_intr = aft_chipcfg_a108_get_dma_intr_stats(a108_reg); + wdt_port_intr = aft_chipcfg_a108_get_wdt_intr_stats(a108_reg); + tdmv_port_intr = aft_chipcfg_a108_get_tdmv_intr_stats(a108_reg); + + }else if(IS_56K_CARD(card)){ + __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &a56k_reg); + fifo_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_FIFO_INTR_BIT,&a56k_reg); + dma_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_DMA_INTR_BIT,&a56k_reg); + wdt_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_WDT_INTR_BIT,&a56k_reg); + }else{ + fifo_port_intr = aft_chipcfg_get_hdlc_intr_stats(reg); + dma_port_intr = aft_chipcfg_get_dma_intr_stats(reg); + wdt_port_intr = aft_chipcfg_get_wdt_intr_stats(reg); + tdmv_port_intr = aft_chipcfg_get_tdmv_intr_stats(reg); + + if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + tdmv_port_intr&=0x01; + } + } + + if (tdmv_port_intr || + dma_port_intr || + fifo_port_intr || + dma_port_intr || + wdt_port_intr) { + /* Pass Through */ + } else { + /* No more interrupts for us */ + goto aft_global_isr_exit; + } + + if (wan_test_bit(AFT_LCFG_FIFO_INTR_BIT,&card->u.aft.lcfg_reg) && + wan_test_bit(card->wandev.comm_port,&fifo_port_intr)){ +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.multicast++; +#endif + wp_aft_fifo_per_port_isr(card); + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + } + +#if 1 + if (wan_test_bit(AFT_LCFG_DMA_INTR_BIT,&card->u.aft.lcfg_reg) && + wan_test_bit(card->wandev.comm_port,&dma_port_intr)){ + + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + + wp_aft_dma_per_port_isr(card); + + /* Only enable fifo interrupts after a first + * successful DMA interrupt */ +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_length_errors++; +#endif + +#if 1 + if (wan_test_bit(0,&card->u.aft.comm_enabled) && + !wan_test_bit(AFT_LCFG_FIFO_INTR_BIT,&card->u.aft.lcfg_reg)){ + aft_fifo_intr_ctrl(card, 1); + } +#else +#warning "FIFO Interrupt Disabled" +#endif + } +#else +#warning "NCDEBUG DMA IGNORED" +#endif + + if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + + if (tdmv_port_intr && + !wan_test_bit(AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT,®)) { + + int ring_buf_enabled=wan_test_bit(AFT_CHIPCFG_A108_A104_TDM_DMA_RINGBUF_BIT,®); + sdla_t *tmp_card; + int ring_rsync=0; + void **card_list; + int i; + + + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_crc_errors++; +#endif + + if (ring_buf_enabled) { + if (card->adptr_type == A104_ADPTR_4TE1 && + card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { + wan_set_bit(AFT_CHIPCFG_A104_TDM_ACK_BIT,®); + } else { + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_RX_INTR_ACK,®); + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK,®); + } + __sdla_bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + + if (card->hw_iface.fe_test_bit(card->hw,1)) { + DEBUG_EVENT("%s: Global TDM Ring Resync\n",card->devname); + ring_rsync=1; + card->hw_iface.fe_clear_bit(card->hw,1); + } + } + + card_list=__sdla_get_ptr_isr_array(card->hw); + for (i=0;i<8;i++){ + tmp_card=(sdla_t*)card_list[i]; + if (tmp_card && + tmp_card->wandev.state == WAN_CONNECTED && + wan_test_bit(AFT_LCFG_TDMV_INTR_BIT,&tmp_card->u.aft.lcfg_reg)) { +#ifdef AFT_IRQ_STAT_DEBUG + tmp_card->wandev.stats.rx_crc_errors++; +#endif + + if (ring_buf_enabled) { + if (ring_rsync) { + aft_tdm_ring_rsync(tmp_card); + } else { + tmp_card->u.aft.tdm_rx_dma_toggle++; + if (tmp_card->u.aft.tdm_rx_dma_toggle >= AFT_TDMV_CIRC_BUF_LEN) { + tmp_card->u.aft.tdm_rx_dma_toggle=0; + } + + tmp_card->u.aft.tdm_tx_dma_toggle++; + if (tmp_card->u.aft.tdm_tx_dma_toggle >= AFT_TDMV_CIRC_BUF_LEN) { + tmp_card->u.aft.tdm_tx_dma_toggle=0; + } + } + } + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (tmp_card->wan_tdmv.sc && + !tmp_card->u.aft.rtp_len) { + aft_voice_span_rx_tx(tmp_card, + ring_buf_enabled); + }else +#endif + { + wp_aft_tdmv_per_port_isr(tmp_card); + } + } + } + + if (!ring_buf_enabled) { + if (card->adptr_type == A104_ADPTR_4TE1 && + card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { + wan_set_bit(AFT_CHIPCFG_A104_TDM_ACK_BIT,®); + } else { + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_RX_INTR_ACK,®); + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK,®); + } + __sdla_bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + } + } + + } else { + + if (wan_test_bit(AFT_LCFG_TDMV_INTR_BIT,&card->u.aft.lcfg_reg) && + wan_test_bit(card->wandev.comm_port,&tdmv_port_intr)){ + + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_crc_errors++; +#endif +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc && + !card->u.aft.rtp_len && + card->wandev.config_id != WANCONFIG_AFT_ANALOG) { + u32 dmareg; + aft_voice_span_rx_tx(card, 0); + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),&dmareg); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,&dmareg); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,&dmareg); + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),dmareg); + } else +#endif + { + wp_aft_tdmv_per_port_isr(card); + } + } + } + + if (wan_test_bit(card->wandev.comm_port,&wdt_port_intr)){ + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + wp_aft_wdt_per_port_isr(card,1); + card->u.aft.wdt_tx_cnt=SYSTEM_TICKS; +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_fifo_errors++; +#endif + } + +#ifdef AFT_WDT_ENABLE + else if (card->wandev.state == WAN_CONNECTED && + SYSTEM_TICKS-card->u.aft.wdt_tx_cnt > (HZ>>2)){ + wp_aft_wdt_per_port_isr(card,0); + card->u.aft.wdt_tx_cnt=SYSTEM_TICKS; +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.tx_aborted_errors++; +#endif + } +#endif + + /* -----------------2/6/2003 10:36AM----------------- + * Finish of the interupt handler + * --------------------------------------------------*/ + + +#if AFT_SECURITY_CHECK + + reg=reg_sec; + if (wan_test_bit(AFT_CHIPCFG_SECURITY_STAT_BIT,®)){ + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + if (++card->u.aft.chip_security_cnt > AFT_MAX_CHIP_SECURITY_CNT){ + DEBUG_EVENT("%s: Critical: AFT Chip Security Compromised: Disabling Driver!(%08X)\n", + card->devname, reg); + DEBUG_EVENT("%s: Please call Sangoma Tech Support (www.sangoma.com)!\n", + card->devname); + + aft_critical_shutdown(card); + } + + } else if (aft_hwdev[card->wandev.card_type].aft_check_ec_security(card)){ + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + + if (++card->u.aft.chip_security_cnt > AFT_MAX_CHIP_SECURITY_CNT){ + DEBUG_EVENT("%s: Critical: Echo Canceller Chip Security Compromised: Disabling Driver!\n", + card->devname); + DEBUG_EVENT("%s: Please call Sangoma Tech Support (www.sangoma.com)!\n", + card->devname); + + card->u.aft.chip_security_cnt=0; + aft_critical_shutdown(card); + } + + } else if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID && + card->wandev.state == WAN_CONNECTED && + SYSTEM_TICKS-card->u.aft.sec_chk_cnt > HZ) { + + u32 lcfg_reg; + + card->u.aft.sec_chk_cnt=SYSTEM_TICKS; + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), &lcfg_reg); + card->u.aft.lcfg_reg=lcfg_reg; + if (wan_test_bit(AFT_LCFG_TX_FE_SYNC_STAT_BIT,&lcfg_reg) || + wan_test_bit(AFT_LCFG_RX_FE_SYNC_STAT_BIT,&lcfg_reg)){ + if (++card->u.aft.chip_security_cnt > AFT_MAX_CHIP_SECURITY_CNT){ + DEBUG_EVENT("%s: Critical: A108 Lost Sync with Front End: Disabling Driver (0x%08X : A108S=0x%08X)!\n", + card->devname, + lcfg_reg,a108_reg); + DEBUG_EVENT("%s: Please call Sangoma Tech Support (www.sangoma.com)!\n", + card->devname); + + aft_critical_shutdown(card); + } + } else { + card->u.aft.chip_security_cnt=0; + } + } else { + card->u.aft.chip_security_cnt=0; + } +#endif + + DEBUG_TEST("---- ISR end.-------------------\n"); + +aft_global_isr_exit: + + wan_clear_bit(0,&card->in_isr); + WAN_IRQ_RETURN(irq_ret); +} + +static void wp_aft_dma_per_port_isr(sdla_t *card) +{ + int i; + u32 dma_tx_reg,dma_rx_reg; + private_area_t *chan; + u32 dma_tx_voice=0; + + /* -----------------2/6/2003 9:37AM------------------ + * Checking for Interrupt source: + * 1. Receive DMA Engine + * 2. Transmit DMA Engine + * 3. Error conditions. + * --------------------------------------------------*/ + + int num_of_logic_ch; + num_of_logic_ch=card->u.aft.num_of_time_slots; + + /* Zaptel optimization. Dont waist time looking at + channels, when we know that only a single DCHAN + will use this code */ +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc) { + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG),&dma_rx_reg); + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG),&dma_tx_reg); + if (card->u.aft.tdmv_dchan) { + chan=(private_area_t*)card->u.aft.dev_to_ch_map[card->u.aft.tdmv_dchan-1]; + if (chan && wan_test_bit(0,&chan->up)) { + aft_dma_rx_complete(card,chan,0); + aft_dma_tx_complete(card,chan,0,0); + } + } + goto isr_skb_rx; + } +#endif + + /* Receive DMA Engine */ + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG),&dma_rx_reg); + + dma_rx_reg&=card->u.aft.active_ch_map; + + if (dma_rx_reg == 0){ + goto isr_skb_rx; + } + + dma_rx_reg &= card->u.aft.logic_ch_map; + dma_rx_reg &= ~(card->u.aft.tdm_logic_ch_map); + + + for (i=0; iu.aft.dev_to_ch_map[i]; + if (!chan){ + DEBUG_EVENT("%s: Error: No Dev for Rx logical ch=%d\n", + card->devname,i); + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + if (chan->channelized_cfg && !chan->hdlc_eng){ + wan_set_bit(i,&dma_tx_voice); + continue; + } + +#if 0 + chan->if_stats.rx_frame_errors++; +#endif + + DEBUG_ISR("%s: RX Interrupt pend. \n", + card->devname); + + aft_dma_rx_complete(card,chan,0); + + +#if 0 + if (chan->cfg.tdmv_master_if && !chan->tdmv_irq_cfg){ + aft_channel_rxintr_ctrl(card,chan,1); + DEBUG_EVENT("%s: Master dev %s Synched to master irq\n", + card->devname,chan->if_name); + chan->tdmv_irq_cfg=1; + } +#endif + } + } + + +isr_skb_rx: + + /* Transmit DMA Engine */ + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG),&dma_tx_reg); + + dma_tx_reg&=card->u.aft.active_ch_map; + + dma_tx_reg&=~dma_tx_voice; + + if (dma_tx_reg == 0){ + goto isr_skb_tx; + } + + dma_tx_reg &= card->u.aft.logic_ch_map; + dma_tx_reg &= ~(card->u.aft.tdm_logic_ch_map); + + + for (i=0; iu.aft.dev_to_ch_map[i]; + if (!chan){ + DEBUG_EVENT("%s: Error: No Dev for Tx logical ch=%d\n", + card->devname,i); + continue; + } + + if (chan->channelized_cfg && !chan->hdlc_eng){ + continue; + } + + DEBUG_ISR("---- TX Interrupt pend. --\n"); + aft_dma_tx_complete(card,chan,0,0); + } + } + +isr_skb_tx: + DEBUG_ISR("---- ISR SKB TX end.-------------------\n"); + + +} + +static void wp_aft_tdmv_per_port_isr(sdla_t *card) +{ + int i; + private_area_t *chan; + +#if 0 + DEBUG_EVENT("%s: TDMV Interrupt LogicCh=%i\n", + card->devname,card->u.aft.num_of_time_slots); +#endif + /* -----------------2/6/2003 9:37AM------------------ + * Checking for Interrupt source: + * 1. Receive DMA Engine + * 2. Transmit DMA Engine + * 3. Error conditions. + * --------------------------------------------------*/ + + + for (i=0; iu.aft.num_of_time_slots;i++){ + + if (!wan_test_bit(i,&card->u.aft.tdm_logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + DEBUG_EVENT("%s: Error: No Dev for Rx logical ch=%d\n", + card->devname,i); + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_dma_rx_tdmv(card,chan); + } + +#if 0 + chan->if_stats.rx_frame_errors++; +#endif + + DEBUG_ISR("%s: RX Interrupt pend. \n", + card->devname); + + } +} + + + + + +static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr) +{ + int i,wdt_disable = 0; + int timeout=AFT_WDTCTRL_TIMEOUT; + + aft_wdt_reset(card); + + if (card->rsync_timeout){ + if (SYSTEM_TICKS - card->rsync_timeout > 3*HZ) { + card->rsync_timeout=0; + if (card->fe.fe_status == FE_CONNECTED) { + DEBUG_EVENT("%s: TDM IRQ Timeout \n", + card->devname); + wan_set_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } + } + aft_wdt_set(card,timeout); + return; + } + + for (i=0; iu.aft.num_of_time_slots;i++){ + + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up) || + wan_test_bit(0,&chan->interface_down)){ + continue; + } + +#if 0 + if (wdt_intr){ + ++chan->if_stats.tx_dropped; + }else{ + ++chan->if_stats.tx_errors; + } +#endif + + if (card->wandev.state == WAN_CONNECTED){ + + if (chan->single_dma_chain){ + wdt_disable=1; + continue; + } +#if 0 + ++chan->if_stats.tx_errors; +#endif + aft_dma_tx_complete (card,chan,1,0); + + } + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + else{ + if (chan->tdmv_zaptel_cfg && + wan_test_bit(0,&chan->up) && + chan->cfg.tdmv_master_if){ + /* If the line becomes disconnected + * keep calling TDMV zaptel in order to + * provide timing */ + if (wdt_intr && chan->cfg.tdmv_master_if){ + int i, err; + void **card_list=__sdla_get_ptr_isr_array(card->hw); + sdla_t *tmp_card; + for (i=0;i<8;i++) { + tmp_card=card_list[i]; + if (!tmp_card) { + continue; + } + if (tmp_card != card) { + /* Only run timing from a first + configured single card */ + DEBUG_TEST("%s: Disabling zaptel timing ! \n",card->devname); + return; + } else { + break; + } + } +#if 0 + ++chan->if_stats.tx_dropped; +#endif + +#if 1 + timeout=1; + aft_wdt_set(card,timeout); + WAN_TDMV_CALL(rx_tx_span, (card), err); +#else +#warning "NCDEBUG: rx_tx_span disabled poll" +#endif + return; + } + } + } +#endif + } + +#ifdef AFT_WDT_ENABLE + /* Since this fucntion can be called via interrupt or + * via interrupt poll, only re-enable wdt interrupt + * if the function was called from the wdt_intr + * not from wdt poll */ + if (!wdt_disable && wdt_intr){ + aft_wdt_set(card,timeout); + } +#endif + + return; + +} + +/**SECTION*********************************************************** + * + * WANPIPE Debugging Interfaces + * + ********************************************************************/ + + + +/*============================================================================= + * process_udp_mgmt_pkt + * + * Process all "wanpipemon" debugger commands. This function + * performs all debugging tasks: + * + * Line Tracing + * Line/Hardware Statistics + * Protocol Statistics + * + * "wanpipemon" utility is a user-space program that + * is used to debug the WANPIPE product. + * + */ +#if 1 +static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, + private_area_t* chan, int local_dev ) +{ + unsigned short buffer_length; + wan_udp_pkt_t *wan_udp_pkt; + wan_trace_t *trace_info=NULL; + + wan_udp_pkt = (wan_udp_pkt_t *)chan->udp_pkt_data; + + if (wan_atomic_read(&chan->udp_pkt_len) == 0){ + return -ENODEV; + } + + trace_info=&chan->trace_info; + wan_udp_pkt = (wan_udp_pkt_t *)chan->udp_pkt_data; + + { + + netskb_t *skb; + + wan_udp_pkt->wan_udp_opp_flag = 0; + + switch(wan_udp_pkt->wan_udp_command) { + + case READ_CONFIGURATION: + wan_udp_pkt->wan_udp_return_code = 0; + wan_udp_pkt->wan_udp_data_len=0; + break; + + case READ_CODE_VERSION: + wan_udp_pkt->wan_udp_return_code = 0; + wan_udp_pkt->wan_udp_data[0]=card->u.aft.firm_ver; + wan_udp_pkt->wan_udp_data_len=1; + break; + + case AFT_LINK_STATUS: + wan_udp_pkt->wan_udp_return_code = 0; + if (card->wandev.state == WAN_CONNECTED){ + wan_udp_pkt->wan_udp_data[0]=1; + }else{ + wan_udp_pkt->wan_udp_data[0]=0; + } + wan_udp_pkt->wan_udp_data_len=1; + break; + + case AFT_MODEM_STATUS: + wan_udp_pkt->wan_udp_return_code = 0; + if (card->wandev.state == WAN_CONNECTED){ + wan_udp_pkt->wan_udp_data[0]=0x28; + }else{ + wan_udp_pkt->wan_udp_data[0]=0; + } + wan_udp_pkt->wan_udp_data_len=1; + break; + + case DIGITAL_LOOPTEST: + wan_udp_pkt->wan_udp_return_code = + digital_loop_test(card,wan_udp_pkt); + break; + + case READ_OPERATIONAL_STATS: + wan_udp_pkt->wan_udp_return_code = 0; + memcpy(wan_udp_pkt->wan_udp_data,&chan->opstats,sizeof(aft_op_stats_t)); + wan_udp_pkt->wan_udp_data_len=sizeof(aft_op_stats_t); + break; + + case FLUSH_OPERATIONAL_STATS: + wan_udp_pkt->wan_udp_return_code = 0; + memset(&chan->opstats,0,sizeof(aft_op_stats_t)); + wan_udp_pkt->wan_udp_data_len=0; + break; + + case READ_COMMS_ERROR_STATS: + wan_udp_pkt->wan_udp_return_code = 0; + memcpy(wan_udp_pkt->wan_udp_data,&chan->errstats,sizeof(aft_comm_err_stats_t)); + wan_udp_pkt->wan_udp_data_len=sizeof(aft_comm_err_stats_t); + break; + + case FLUSH_COMMS_ERROR_STATS: + wan_udp_pkt->wan_udp_return_code = 0; + memset(&chan->errstats,0,sizeof(aft_comm_err_stats_t)); + wan_udp_pkt->wan_udp_data_len=0; + break; + + + case ENABLE_TRACING: + + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = 0; + + if (!wan_test_bit(0,&trace_info->tracing_enabled)){ + + trace_info->trace_timeout = SYSTEM_TICKS; + + wan_trace_purge(trace_info); + + if (wan_udp_pkt->wan_udp_data[0] == 0){ + wan_clear_bit(1,&trace_info->tracing_enabled); + DEBUG_UDP("%s: ADSL L3 trace enabled!\n", + card->devname); + }else if (wan_udp_pkt->wan_udp_data[0] == 1){ + wan_clear_bit(2,&trace_info->tracing_enabled); + wan_set_bit(1,&trace_info->tracing_enabled); + DEBUG_UDP("%s: ADSL L2 trace enabled!\n", + card->devname); + }else{ + wan_clear_bit(1,&trace_info->tracing_enabled); + wan_set_bit(2,&trace_info->tracing_enabled); + DEBUG_UDP("%s: ADSL L1 trace enabled!\n", + card->devname); + } + wan_set_bit (0,&trace_info->tracing_enabled); + + }else{ + DEBUG_EVENT("%s: Error: ATM trace running!\n", + card->devname); + wan_udp_pkt->wan_udp_return_code = 2; + } + + break; + + case DISABLE_TRACING: + + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + + if(wan_test_bit(0,&trace_info->tracing_enabled)) { + + wan_clear_bit(0,&trace_info->tracing_enabled); + wan_clear_bit(1,&trace_info->tracing_enabled); + wan_clear_bit(2,&trace_info->tracing_enabled); + + wan_trace_purge(trace_info); + + DEBUG_UDP("%s: Disabling AFT trace\n", + card->devname); + + }else{ + /* set return code to line trace already + disabled */ + wan_udp_pkt->wan_udp_return_code = 1; + } + + break; + + case GET_TRACE_INFO: + + if(wan_test_bit(0,&trace_info->tracing_enabled)){ + trace_info->trace_timeout = SYSTEM_TICKS; + }else{ + DEBUG_EVENT("%s: Error ATM trace not enabled\n", + card->devname); + /* set return code */ + wan_udp_pkt->wan_udp_return_code = 1; + break; + } + + buffer_length = 0; + wan_udp_pkt->wan_udp_atm_num_frames = 0; + wan_udp_pkt->wan_udp_atm_ismoredata = 0; + +#if defined(__FreeBSD__) || defined(__OpenBSD__) + while (wan_skb_queue_len(&trace_info->trace_queue)){ + WAN_IFQ_POLL(&trace_info->trace_queue, skb); + if (skb == NULL){ + DEBUG_EVENT("%s: No more trace packets in trace queue!\n", + card->devname); + break; + } + if ((WAN_MAX_DATA_SIZE - buffer_length) < skb->m_pkthdr.len){ + /* indicate there are more frames on board & exit */ + wan_udp_pkt->wan_udp_atm_ismoredata = 0x01; + break; + } + + m_copydata(skb, + 0, + skb->m_pkthdr.len, + &wan_udp_pkt->wan_udp_data[buffer_length]); + buffer_length += skb->m_pkthdr.len; + WAN_IFQ_DEQUEUE(&trace_info->trace_queue, skb); + if (skb){ + wan_skb_free(skb); + } + wan_udp_pkt->wan_udp_atm_num_frames++; + } +#elif defined(__LINUX__) + while ((skb=skb_dequeue(&trace_info->trace_queue)) != NULL){ + + if((MAX_TRACE_BUFFER - buffer_length) < wan_skb_len(skb)){ + /* indicate there are more frames on board & exit */ + wan_udp_pkt->wan_udp_atm_ismoredata = 0x01; + if (buffer_length != 0){ + wan_skb_queue_head(&trace_info->trace_queue, skb); + }else{ + /* If rx buffer length is greater than the + * whole udp buffer copy only the trace + * header and drop the trace packet */ + + memcpy(&wan_udp_pkt->wan_udp_atm_data[buffer_length], + wan_skb_data(skb), + sizeof(wan_trace_pkt_t)); + + buffer_length = sizeof(wan_trace_pkt_t); + wan_udp_pkt->wan_udp_atm_num_frames++; + wan_skb_free(skb); + } + break; + } + + memcpy(&wan_udp_pkt->wan_udp_atm_data[buffer_length], + wan_skb_data(skb), + wan_skb_len(skb)); + + buffer_length += wan_skb_len(skb); + wan_skb_free(skb); + wan_udp_pkt->wan_udp_atm_num_frames++; + } +#endif + /* set the data length and return code */ + wan_udp_pkt->wan_udp_data_len = buffer_length; + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + break; + + case ROUTER_UP_TIME: + wan_getcurrenttime(&chan->router_up_time, NULL); + chan->router_up_time -= chan->router_start_time; + *(unsigned long *)&wan_udp_pkt->wan_udp_data = + chan->router_up_time; + wan_udp_pkt->wan_udp_data_len = sizeof(unsigned long); + wan_udp_pkt->wan_udp_return_code = 0; + break; + + case WAN_GET_MEDIA_TYPE: + if (card->wandev.fe_iface.get_fe_media){ + wan_udp_pkt->wan_udp_data[0] = + card->wandev.fe_iface.get_fe_media(&card->fe); + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + }else{ + wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; + } + break; +#if 0 + case WAN_FE_GET_STAT: + case WAN_FE_SET_LB_MODE: + case WAN_FE_FLUSH_PMON: + case WAN_FE_GET_CFG: + case WAN_FE_SET_DEBUG_MODE: + case WAN_FE_TX_MODE: + + if (IS_TE1_CARD(card)){ + wan_smp_flag_t smp_flags; + card->hw_iface.hw_lock(card->hw,&smp_flags); + card->wandev.fe_iface.process_udp( + &card->fe, + &wan_udp_pkt->wan_udp_cmd, + &wan_udp_pkt->wan_udp_data[0]); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + }else{ + wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; + } + break; +#endif + + case WAN_GET_PROTOCOL: + wan_udp_pkt->wan_udp_aft_num_frames = card->wandev.config_id; + wan_udp_pkt->wan_udp_return_code = CMD_OK; + wan_udp_pkt->wan_udp_data_len = 1; + break; + + case WAN_GET_PLATFORM: + wan_udp_pkt->wan_udp_data[0] = WAN_PLATFORM_ID; + wan_udp_pkt->wan_udp_return_code = CMD_OK; + wan_udp_pkt->wan_udp_data_len = 1; + break; + + case WAN_GET_MASTER_DEV_NAME: + wan_udp_pkt->wan_udp_data_len = 0; + wan_udp_pkt->wan_udp_return_code = 0xCD; + break; + + case AFT_HWEC_STATUS: + *(unsigned long *)&wan_udp_pkt->wan_udp_data[0] = + IS_E1_CARD(card) ? card->wandev.ec_map: + card->wandev.ec_map << 1; + wan_udp_pkt->wan_udp_data_len = sizeof(unsigned long); + wan_udp_pkt->wan_udp_return_code = 0; + break; + + default: + if ((wan_udp_pkt->wan_udp_command & 0xF0) == WAN_FE_UDP_CMD_START){ + /* FE udp calls */ + wan_smp_flag_t smp_flags,smp_flags1; + + card->hw_iface.hw_lock(card->hw,&smp_flags); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags1); + card->wandev.fe_iface.process_udp( + &card->fe, + &wan_udp_pkt->wan_udp_cmd, + &wan_udp_pkt->wan_udp_data[0]); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags1); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + break; + } + wan_udp_pkt->wan_udp_data_len = 0; + wan_udp_pkt->wan_udp_return_code = 0xCD; + + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT( + "%s: Warning, Illegal UDP command attempted from network: %x\n", + card->devname,wan_udp_pkt->wan_udp_command); + } + break; + } /* end of switch */ + } /* end of else */ + + /* Fill UDP TTL */ + wan_udp_pkt->wan_ip_ttl= card->wandev.ttl; + + wan_udp_pkt->wan_udp_request_reply = UDPMGMT_REPLY; + return 1; + +} +#endif + + + +/**SECTION************************************************************* + * + * TASK Functions and Triggers + * + **********************************************************************/ + + +/*============================================================================ + * port_set_state + * + * Set PORT state. + * + */ +static void port_set_state (sdla_t *card, int state) +{ + struct wan_dev_le *devle; + netdevice_t *dev; + + if (card->wandev.state != state) + { +#if 0 + switch (state) + { + case WAN_CONNECTED: + DEBUG_EVENT( "%s: Front End Link connected!\n", + card->devname); + break; + + case WAN_CONNECTING: + DEBUG_EVENT( "%s: Front End Link connecting...\n", + card->devname); + break; + + case WAN_DISCONNECTED: + DEBUG_EVENT( "%s: Front End Link disconnected!\n", + card->devname); + break; + } +#endif + card->wandev.state = state; + WAN_LIST_FOREACH(devle, &card->wandev.dev_head, dev_link){ + dev = WAN_DEVLE2DEV(devle); + if (!dev) continue; + set_chan_state(card, dev, state); + } + } +} + +/*============================================================ + * handle_front_end_state + * + * Front end state indicates the physical medium that + * the Z80 backend connects to. + * + * S514-1/2/3: V32/RS232/FT1 Front End + * Front end state is determined via + * Modem/Status. + * S514-4/5/7/8: 56K/T1/E1 Front End + * Front end state is determined via + * link status interrupt received + * from the front end hardware. + * + * If the front end state handler is enabed by the + * user. The interface state will follow the + * front end state. I.E. If the front end goes down + * the protocol and interface will be declared down. + * + * If the front end state is UP, then the interface + * and protocol will be up ONLY if the protocol is + * also UP. + * + * Therefore, we must have three state variables + * 1. Front End State (card->wandev.front_end_status) + * 2. Protocol State (card->wandev.state) + * 3. Interface State (dev->flags & IFF_UP) + * + */ + +static void handle_front_end_state(void *card_id) +{ + sdla_t *card = (sdla_t*)card_id; + + if (!wan_test_bit(AFT_CHIP_CONFIGURED,&card->u.aft.chip_cfg_status) && + card->fe.fe_status == FE_CONNECTED) { + DEBUG_TEST("%s: Skipping Front Front End State = %x\n", + card->devname,card->fe.fe_status); + + wan_set_bit(AFT_FRONT_END_UP,&card->u.aft.chip_cfg_status); + return; + } + + + if (card->wandev.ignore_front_end_status == WANOPT_YES) { + if (card->wandev.state != WAN_CONNECTED){ + enable_data_error_intr(card); + port_set_state(card,WAN_CONNECTED); + wan_set_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); + } + return; + } + + if (card->fe.fe_status == FE_CONNECTED){ + if (card->wandev.state != WAN_CONNECTED){ + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc){ + int err; + WAN_TDMV_CALL(state, (card, WAN_CONNECTED), err); + } +#endif + /* WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); */ + + if (card->tdmv_conf.span_no && + !wan_test_bit(0,&card->u.aft.tdmv_master_if_up)){ + DEBUG_EVENT("%s: Skipping AFT Communication wait for MasterIF\n", + card->devname); + return; + } + + enable_data_error_intr(card); + port_set_state(card,WAN_CONNECTED); + wan_set_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); + + } + }else{ + if (card->wandev.state == WAN_CONNECTED){ + port_set_state(card,WAN_DISCONNECTED); + disable_data_error_intr(card,LINK_DOWN); + + wan_set_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); + /* We are already in the poll task here so + * no need to schedule. because next check in the + * poll routine would be the AFT_FE_LED */ + /* WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); */ + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc){ + int err; + WAN_TDMV_CALL(state, (card, WAN_DISCONNECTED), err); + } +#endif + } + } + +} + +unsigned char aft_read_cpld(sdla_t *card, unsigned short cpld_off) +{ + return aft_hwdev[card->wandev.card_type].aft_read_cpld(card,cpld_off); +} + +int aft_write_cpld(void *pcard, unsigned short off,unsigned char data) +{ + sdla_t *card = (sdla_t *)pcard; + return aft_hwdev[card->wandev.card_type].aft_write_cpld(card,off,data); +} + +#if 0 +/*============================================================================ + * Read TE1/56K Front end registers + */ +static unsigned char +write_front_end_reg (void* card1, unsigned short off, unsigned char value) +{ + sdla_t* card = (sdla_t*)card1; + + if (card->wandev.card_type == WANOPT_AFT_ANALOG){ + DEBUG_EVENT("%s: Internal Error (%s:%d)\n", + card->devname, __FUNCTION__,__LINE__); + return 0x00; + } + return aft_hwdev[card->wandev.card_type].aft_write_fe(card1,off,value); +} + +/*============================================================================ + * Read TE1/56K Front end registers + */ +static unsigned char +read_front_end_reg (void* card1, unsigned short off) +{ + sdla_t* card = (sdla_t*)card1; + + if (card->wandev.card_type == WANOPT_AFT_ANALOG){ + DEBUG_EVENT("%s: Internal Error (%s:%d)\n", + card->devname, __FUNCTION__,__LINE__); + return 0x00; + } + return aft_hwdev[card->wandev.card_type].aft_read_fe(card1,off); +} +#endif + +static unsigned char +aft_write_ec (void* card1, unsigned short off, unsigned char value) +{ + DEBUG_EVENT("ADEBUG: Write Octasic Offset %04X Value %02X!\n", + off, value); + return 0; +} + +/*============================================================================ + * Read from Octasic board + */ +static unsigned char +aft_read_ec (void* card1, unsigned short off) +{ + u8 value = 0x00; + + DEBUG_EVENT("ADEBUG: Read Octasic offset %04X Value %02X (temp)!\n", + off, value); + return value; +} + + + +static int aft_read(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + WAN_ASSERT(card == NULL); + WAN_ASSERT(api_cmd == NULL); + + if(api_cmd->len == 1){ + if (api_cmd->offset <= 0x3C){ + card->hw_iface.pci_read_config_byte( + card->hw, + api_cmd->offset, + (u8*)&api_cmd->data[0]); + }else{ + card->hw_iface.bus_read_1( + card->hw, + api_cmd->offset, + (u8*)&api_cmd->data[0]); + } + }else if (api_cmd->len == 2){ + if (api_cmd->offset <= 0x3C){ + card->hw_iface.pci_read_config_word( + card->hw, + api_cmd->offset, + (u16*)&api_cmd->data[0]); + }else{ + card->hw_iface.bus_read_2( + card->hw, + api_cmd->offset, + (u16*)&api_cmd->data[0]); + } + }else if (api_cmd->len == 4){ + if (api_cmd->offset <= 0x3C){ + card->hw_iface.pci_read_config_dword(card->hw, + api_cmd->offset, + (u32*)&api_cmd->data[0]); + }else{ + WAN_ASSERT(card->hw_iface.bus_read_4 == NULL); + card->hw_iface.bus_read_4( + card->hw, + api_cmd->offset, + (u32*)&api_cmd->data[0]); + } + }else{ + card->hw_iface.peek(card->hw, + api_cmd->offset, + &api_cmd->data[0], + api_cmd->len); + } + +#if defined(DEBUG_REG) + DEBUG_EVENT("%s: Reading Bar%d Offset=0x%X Data=%08X Len=%d\n", + card->devname, + api_cmd->bar, + api_cmd->offset, + *(u32*)&api_cmd->data[0], + api_cmd->len); +#endif + + return 0; +} + +static int aft_fe_read(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + wan_smp_flag_t smp_flags; + + card->hw_iface.hw_lock(card->hw,&smp_flags); + api_cmd->data[0] = (u8)card->fe.read_fe_reg(card, (int)api_cmd->offset); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + +#ifdef DEB_XILINX + DEBUG_EVENT("%s: Reading Bar%d Offset=0x%X Len=%d Val=%02X\n", + card->devname,api_cmd->bar,api_cmd->offset,api_cmd->len, api_cmd->data[0]); +#endif + + return 0; +} + +static int aft_write(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + + if (api_cmd->len == 1){ + card->hw_iface.bus_write_1( + card->hw, + api_cmd->offset, + *(u8*)&api_cmd->data[0]); +#if defined(DEBUG_REG) + DEBUG_EVENT("%s: Write Offset=0x%08X Data=0x%02X\n", + card->devname,api_cmd->offset, + *(u8*)&api_cmd->data[0]); +#endif + }else if (api_cmd->len == 2){ + card->hw_iface.bus_write_2( + card->hw, + api_cmd->offset, + *(u16*)&api_cmd->data[0]); +#if defined(DEBUG_REG) + DEBUG_EVENT("%s: Write Offset=0x%08X Data=0x%04X\n", + card->devname,api_cmd->offset, + *(unsigned short*)&api_cmd->data[0]); +#endif + }else if (api_cmd->len == 4){ + card->hw_iface.bus_write_4( + card->hw, + api_cmd->offset, + *(unsigned int*)&api_cmd->data[0]); +#if defined(DEBUG_REG) + DEBUG_EVENT("ADEBUG: %s: Write Offset=0x%08X Data=0x%08X\n", + card->devname,api_cmd->offset, + *(u32*)&api_cmd->data[0]); +#endif + }else{ + card->hw_iface.poke( + card->hw, + api_cmd->offset, + (u8*)&api_cmd->data[0], + api_cmd->len); +#if 0 + memcpy_toio((unsigned char*)vector, + (unsigned char*)&api_cmd->data[0], api_cmd->len); +#endif + } + + return 0; +} + +static int aft_fe_write(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + wan_smp_flag_t smp_flags; + +#ifdef DEB_XILINX + DEBUG_EVENT("%s: Writting Bar%d Offset=0x%X Len=%d Val=%02X\n", + card->devname, + api_cmd->bar, + api_cmd->offset, + api_cmd->len, + api_cmd->data[0]); +#endif + + + card->hw_iface.hw_lock(card->hw,&smp_flags); + card->fe.write_fe_reg (card, (int)api_cmd->offset, (int)api_cmd->data[0]); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + return 0; + +} + + + +static int aft_write_bios(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + +#ifdef DEB_XILINX + DEBUG_EVENT("Setting PCI 0xX=0x%08lX 0x3C=0x%08X\n", + (card->wandev.S514_cpu_no[0] == SDLA_CPU_A) ? 0x10 : 0x14, + card->u.aft.bar,card->wandev.irq); +#endif + card->hw_iface.pci_write_config_dword(card->hw, + (card->wandev.S514_cpu_no[0] == SDLA_CPU_A) ? 0x10 : 0x14, + card->u.aft.bar); + card->hw_iface.pci_write_config_dword(card->hw, 0x3C, card->wandev.irq); + card->hw_iface.pci_write_config_dword(card->hw, 0x0C, 0x0000ff00); + + return 0; +} + +#if 0 +extern int OctDrvIoctl(sdla_t*, int cmd, void*); +#endif + +static int aft_hwec(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + +#if 0 + if (api_cmd->offset){ + /* Use direct read/write to/from octasic chip */ + if (api_cmd->len){ + /* Write */ + aft_write_ec (card, api_cmd->offset, api_cmd->data[0]); + }else{ + /* Read */ + api_cmd->data[0] = aft_read_ec (card, api_cmd->offset); + api_cmd->len = 1; + } + }else +#endif + { +#if 0 + OctDrvIoctl(card, api_cmd->cmd, api_cmd->data); +#endif + } + + return 0; +} + +static int aft_devel_ioctl(sdla_t *card, struct ifreq *ifr) +{ + wan_cmd_api_t api_cmd; + int err = -EINVAL; + + if (!ifr || !ifr->ifr_data){ + DEBUG_EVENT("%s: Error: No ifr or ifr_data\n",__FUNCTION__); + return -EFAULT; + } + + if (WAN_COPY_FROM_USER(&api_cmd,ifr->ifr_data,sizeof(wan_cmd_api_t))){ + return -EFAULT; + } + + switch(api_cmd.cmd){ + case SIOC_WAN_READ_REG: + err=aft_read(card, &api_cmd); + break; + case SIOC_WAN_WRITE_REG: + err=aft_write(card, &api_cmd); + break; + + case SIOC_WAN_FE_READ_REG: + err=aft_fe_read(card, &api_cmd); + break; + + case SIOC_WAN_FE_WRITE_REG: + err=aft_fe_write(card, &api_cmd); + break; + + case SIOC_WAN_SET_PCI_BIOS: + err=aft_write_bios(card, &api_cmd); + break; + + case SIOC_WAN_EC_REG: + err = aft_hwec(card, &api_cmd); + break; + } + if (WAN_COPY_TO_USER(ifr->ifr_data,&api_cmd,sizeof(wan_cmd_api_t))){ + return -EFAULT; + } + return err; +} + + +/*========================================= + * enable_data_error_intr + * + * Description: + * + * Run only after the front end comes + * up from down state. + * + * Clean the DMA Tx/Rx pending interrupts. + * (Ignore since we will reconfigure + * all dma descriptors. DMA controler + * was already disabled on link down) + * + * For all channels clean Tx/Rx Fifo + * + * Enable DMA controler + * (This starts the fifo cleaning + * process) + * + * For all channels reprogram Tx/Rx DMA + * descriptors. + * + * Clean the Tx/Rx Error pending interrupts. + * (Since dma fifo's are now empty) + * + * Enable global DMA and Error interrutps. + * + */ + +static void enable_data_error_intr(sdla_t *card) +{ + u32 reg; + int i,err; + + DEBUG_TEST("%s: %s()\n",card->devname,__FUNCTION__); + + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + if (wan_test_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®)){ + DEBUG_EVENT("%s: Warning: Skipping data enable wait for cfg!\n", + card->devname); + return; + } + +#if 0 + aft_list_dma_chain_regs(card); +#endif + + if (card->tdmv_conf.span_no && + !wan_test_bit(0,&card->u.aft.tdmv_master_if_up)){ + DEBUG_EVENT("%s: Critical error: Enable Card while Master If Not up!\n", + card->devname); + } + + if (wan_test_bit(0,&card->u.aft.comm_enabled)){ + disable_data_error_intr(card,LINK_DOWN); + } + + aft_wdt_reset(card); + + /* Clean Tx/Rx DMA interrupts */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG), + ®); + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG), + ®); + + + + err=aft_hwdev[card->wandev.card_type].aft_test_sync(card,0); + if (err){ + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + DEBUG_EVENT("%s: Error: Front End Interface out of sync! (0x%X)\n", + card->devname,reg); + + /*FIXME: How to recover from here, should never happen */ + } + + + if (card->tdmv_conf.span_no){ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + wan_set_bit(AFT_LCFG_TDMV_INTR_BIT,®); + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + } + + for (i=0; iu.aft.num_of_time_slots;i++){ + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + + DEBUG_TEST("%s: 1) Free Used DMA CHAINS %s\n", + card->devname,chan->if_name); + + aft_free_rx_complete_list(chan); + aft_free_rx_descriptors(chan); + + DEBUG_TEST("%s: 1) Free UNUSED DMA CHAINS %s\n", + card->devname,chan->if_name); + + wan_clear_bit(TX_INTR_PENDING,&chan->dma_chain_status); + + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_tx_dma_voice_handler((unsigned long)chan,0,1); + }else{ + aft_tx_dma_chain_handler((unsigned long)chan,0,1); + } + + aft_free_tx_descriptors(chan); + + DEBUG_TEST("%s: 2) Init interface fifo no wait %s\n", + card->devname,chan->if_name); + + aft_tslot_sync_ctrl(card,chan,0); + + aft_init_rx_dev_fifo(card, chan, WP_NO_WAIT); + aft_init_tx_dev_fifo(card, chan, WP_NO_WAIT); + + } + + + /* Enable Global DMA controler, in order to start the + * fifo cleaning */ + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_GLOBAL_INTR_BIT,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + + /* For all channels clean Tx/Rx fifos */ + + for (i=0; iu.aft.num_of_time_slots;i++){ + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + + DEBUG_TEST("%s: 3) Init interface fifo %s\n", + card->devname,chan->if_name); + + aft_init_rx_dev_fifo(card, chan, WP_WAIT); + aft_init_tx_dev_fifo(card, chan, WP_WAIT); + + DEBUG_TEST("%s: Clearing Fifo and idle_flag %s\n", + card->devname,chan->if_name); + wan_clear_bit(0,&chan->idle_start); + } +#if 0 + aft_list_dma_chain_regs(card); +#endif + /* For all channels, reprogram Tx/Rx DMA descriptors. + * For Tx also make sure that the BUSY flag is clear + * and previoulsy Tx packet is deallocated */ + + for (i=0; iu.aft.num_of_time_slots;i++){ + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + DEBUG_TEST("%s: 4) Init interface %s\n", + card->devname,chan->if_name); + + chan->dma_index=0; + memset(chan->dma_history,0,sizeof(chan->dma_history)); + + aft_reset_rx_chain_cnt(chan); + +#if 0 + aft_list_descriptors(chan); +#endif + + aft_dma_rx(card,chan); + aft_tslot_sync_ctrl(card,chan,1); + + DEBUG_TEST("%s: DMA RX SETUP %s\n", + card->devname,chan->if_name); +#if 0 + aft_list_descriptors(chan); +#endif + } + + /* Clean Tx/Rx Error interrupts, since fifos are now + * empty, and Tx fifo may generate an underrun which + * we want to ignore :) */ + + card->u.aft.tdm_rx_dma_toggle=0; + card->u.aft.tdm_tx_dma_toggle=0; + + for (i=0; iu.aft.num_of_time_slots;i++){ + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + if (!chan->hdlc_eng){ + aft_reset_tx_chain_cnt(chan); + aft_dma_tx(card,chan); + } + + if (chan->cfg.ss7_enable){ + aft_clear_ss7_force_rx(card,chan); + } + + if (chan->tdmv_zaptel_cfg && !chan->hdlc_eng){ + aft_dma_rx_tdmv(card,chan); + } + } + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG), + ®); + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG), + ®); + + + /* Enable Global DMA and Error Interrupts */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + + wan_set_bit(AFT_LCFG_DMA_INTR_BIT,®); + wan_clear_bit(AFT_LCFG_FIFO_INTR_BIT,®); + if (card->tdmv_conf.span_no){ + wan_set_bit(AFT_LCFG_TDMV_INTR_BIT,®); + } + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + + card->u.aft.lcfg_reg=reg; + + + wan_set_bit(0,&card->u.aft.comm_enabled); + DEBUG_EVENT("%s: AFT communications enabled!\n", + card->devname); + + /* Enable Channelized Driver if configured */ + if (card->tdmv_conf.span_no) { + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG), + ®); + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG), + ®); + +#if 1 + + + if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + + /* Reset Global Fifo for the whole card */ + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG,®); + wan_set_bit(AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT,®); + card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + + /* Wait for Global Fifo Reset 1ms */ + WP_DELAY(1000); + + /* Clear Global Card Fifo reset */ + wan_clear_bit(AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT,®); + + /* Enable TDM Quad DMA Ring buffer */ + if (wan_test_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status)) { + wan_set_bit(AFT_CHIPCFG_A108_A104_TDM_DMA_RINGBUF_BIT,®); + card->hw_iface.fe_set_bit(card->hw,1); + }else{ + wan_clear_bit(AFT_CHIPCFG_A108_A104_TDM_DMA_RINGBUF_BIT,®); + } + +#if 1 + /* Global Acknowledge TDM Interrupt (Kickstart) */ + if (card->adptr_type == A104_ADPTR_4TE1 && + card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { + wan_set_bit(AFT_CHIPCFG_A104_TDM_ACK_BIT,®); + } else { + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_RX_INTR_ACK,®); + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK,®); + } + +#endif + card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + card->rsync_timeout=SYSTEM_TICKS; + + DEBUG_EVENT("%s: AFT Global TDM Intr\n", + card->devname); + + } else { + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,®); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + DEBUG_EVENT("%s: AFT Per Port TDM Intr\n",card->devname); + } + +#endif + } + + +#ifdef AFT_WDT_ENABLE + aft_wdt_set(card,AFT_WDTCTRL_TIMEOUT); +#endif + + DEBUG_TEST("%s: %s() end: reg=0x%X!\n" + ,card->devname,__FUNCTION__,reg); + AFT_FUNC_DEBUG(); + +} + +static void disable_data_error_intr(sdla_t *card, unsigned char event) +{ + u32 reg; + + DEBUG_TEST("%s: Event = %s\n",__FUNCTION__, + event==DEVICE_DOWN?"Device Down": "Link Down"); + + DEBUG_EVENT("%s: AFT communications disabled!\n", + card->devname); + + aft_wdt_reset(card); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + + wan_clear_bit(AFT_LCFG_DMA_INTR_BIT,®); + wan_clear_bit(AFT_LCFG_FIFO_INTR_BIT,®); + wan_clear_bit(AFT_LCFG_TDMV_INTR_BIT,®); + + if (event==DEVICE_DOWN){ + /* Disable Front End Interface */ + wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®); + } + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + card->u.aft.lcfg_reg=reg; + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_clear_bit(AFT_DMACTRL_GLOBAL_INTR_BIT,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + + + if (event==DEVICE_DOWN){ + wan_set_bit(CARD_DOWN,&card->wandev.critical); + }else{ + if (card->tdmv_conf.span_no){ + DEBUG_EVENT("%s: Starting TDMV 1ms Timer\n", + card->devname); +#ifdef AFT_WDT_ENABLE + aft_wdt_set(card,1); +#endif + } + } + + wan_clear_bit(0,&card->u.aft.comm_enabled); +} + + +/*============================================================================ + * Update communications error and general packet statistics. + */ +static int update_comms_stats(sdla_t* card) +{ + /* 1. On the first timer interrupt, update T1/E1 alarms + * and PMON counters (only for T1/E1 card) (TE1) + */ + + /* TE1 Update T1/E1 alarms */ + if (IS_TE1_CARD(card) && card->hw) { + wan_smp_flag_t smp_flags; + + card->hw_iface.hw_lock(card->hw,&smp_flags); + + if (card->wandev.fe_iface.read_alarm) { + card->wandev.fe_iface.read_alarm(&card->fe, 0); + } + /* TE1 Update T1/E1 perfomance counters */ +#if 0 +#warning "PMON DISABLED DUE TO ERROR" +#else + if (card->wandev.fe_iface.read_pmon) { + wan_smp_flag_t flags; + wan_spin_lock_irq(&card->wandev.lock,&flags); + card->wandev.fe_iface.read_pmon(&card->fe, 0); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + } +#endif + + card->hw_iface.hw_unlock(card->hw,&smp_flags); + } + + return 0; +} + +static void aft_rx_fifo_over_recover(sdla_t *card, private_area_t *chan) +{ + + if (chan->channelized_cfg && !chan->hdlc_eng){ + return; + } + +#if 0 + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s Rx Fifo Recovery!\n", + card->devname,chan->if_name); + } +#endif + + aft_channel_rxdma_ctrl(card, chan, 0); + + aft_tslot_sync_ctrl(card,chan,0); + + aft_free_rx_complete_list(chan); + aft_free_rx_descriptors(chan); + + aft_init_rx_dev_fifo(card, chan, WP_NO_WAIT); + + aft_channel_rxdma_ctrl(card, chan, 1); + + aft_init_rx_dev_fifo(card, chan, WP_WAIT); + + chan->dma_index=0; + memset(chan->dma_history,0,sizeof(chan->dma_history)); + + aft_reset_rx_chain_cnt(chan); + aft_dma_rx(card,chan); + + aft_tslot_sync_ctrl(card,chan,1); + +} + +static void aft_tx_fifo_under_recover (sdla_t *card, private_area_t *chan) +{ + if (chan->channelized_cfg && !chan->hdlc_eng){ + return; + } + +#if 0 + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s Tx Fifo Recovery!\n", + card->devname,chan->if_name); + } +#endif + /* Enable DMA controler, in order to start the + * fifo cleaning */ + + aft_channel_txdma_ctrl(card, chan, 0); + +#if 0 + aft_list_tx_descriptors(chan); +#endif + aft_dma_tx_complete(card,chan,0, 1); + + aft_free_tx_descriptors(chan); + aft_init_tx_dev_fifo(card,chan,WP_NO_WAIT); + + aft_channel_txdma_ctrl(card, chan, 1); + + aft_init_tx_dev_fifo(card,chan,WP_WAIT); + wan_clear_bit(0,&chan->idle_start); + + aft_reset_tx_chain_cnt(chan); + aft_dma_tx(card,chan); + +} + +static int set_chan_state(sdla_t* card, netdevice_t* dev, int state) +{ + private_area_t *chan = wan_netif_priv(dev); + private_area_t *ch_ptr; + + if (!chan){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: %s:%d No chan ptr!\n", + card->devname,__FUNCTION__,__LINE__); + } + return -EINVAL; + } + + chan->common.state = state; + for (ch_ptr=chan; ch_ptr != NULL; ch_ptr=ch_ptr->next){ + ch_ptr->common.state=state; + + if (ch_ptr->tdmv_zaptel_cfg) { + continue; + } + + if (ch_ptr->common.usedby == TDM_VOICE_API || + ch_ptr->common.usedby == TDM_VOICE_DCHAN) { +#ifdef AFT_TDM_API_SUPPORT + if (is_tdm_api(ch_ptr,&ch_ptr->wp_tdm_api_dev)) { + wanpipe_tdm_api_update_state(&ch_ptr->wp_tdm_api_dev, state); + } +#endif + } + } + + if (state == WAN_CONNECTED){ + wan_clear_bit(0,&chan->idle_start); + WAN_NETIF_START_QUEUE(dev); + chan->opstats.link_active_count++; + WAN_NETIF_CARRIER_ON(dev); + WAN_NETIF_WAKE_QUEUE(dev); + }else{ + chan->opstats.link_inactive_modem_count++; + WAN_NETIF_CARRIER_OFF(dev); + WAN_NETIF_STOP_QUEUE(dev); + } + +#if defined(__LINUX__) +# if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) + if (chan->common.usedby == API) { + wan_update_api_state(chan); + } +#endif +#endif + + if (chan->common.usedby == STACK){ + if (state == WAN_CONNECTED){ + wanpipe_lip_connect(chan,0); + }else{ + wanpipe_lip_disconnect(chan,0); + } + } + return 0; +} + + + +/**SECTION************************************************************* + * + * Protocol API Support Functions + * + **********************************************************************/ + + +static int protocol_init (sdla_t *card, netdevice_t *dev, + private_area_t *chan, + wanif_conf_t* conf) +{ + + chan->common.protocol = conf->protocol; + + DEBUG_TEST("%s: Protocol init 0x%X PPP=0x0%x FR=0x0%X\n", + wan_netif_name(dev), chan->common.protocol, + WANCONFIG_PPP, + WANCONFIG_FR); + +#ifndef CONFIG_PRODUCT_WANPIPE_GENERIC + DEBUG_EVENT("%s: AFT Driver doesn't directly support any protocols!\n", + chan->if_name); + return -1; + +#else + if (chan->common.protocol == WANCONFIG_PPP || + chan->common.protocol == WANCONFIG_CHDLC){ + + struct ifreq ifr; + struct if_settings ifsettings; + + wanpipe_generic_register(card, dev, wan_netif_name(dev)); + chan->common.prot_ptr = dev; + + if (chan->common.protocol == WANCONFIG_CHDLC){ + DEBUG_EVENT("%s: Starting Kernel CISCO HDLC protocol\n", + chan->if_name); + ifsettings.type = IF_PROTO_CISCO; + }else{ + DEBUG_EVENT("%s: Starting Kernel Sync PPP protocol\n", + chan->if_name); + ifsettings.type = IF_PROTO_PPP; + + } + ifr.ifr_data = (caddr_t)&ifsettings; + if (wp_lite_set_proto(dev, &ifr)){ + wanpipe_generic_unregister(dev); + return -EINVAL; + } + + }else if (chan->common.protocol == WANCONFIG_GENERIC){ + chan->common.prot_ptr = dev; + + }else{ + DEBUG_EVENT("%s:%s: Unsupported protocol %d\n", + card->devname,chan->if_name,chan->common.protocol); + return -EPROTONOSUPPORT; + } +#endif + + return 0; +} + + +static int protocol_stop (sdla_t *card, netdevice_t *dev) +{ + private_area_t *chan=wan_netif_priv(dev); + int err = 0; + + if (!chan) + return 0; + + return err; +} + +static int protocol_shutdown (sdla_t *card, netdevice_t *dev) +{ + private_area_t *chan=wan_netif_priv(dev); + + if (!chan) + return 0; + +#ifndef CONFIG_PRODUCT_WANPIPE_GENERIC + + return 0; +#else + + if (chan->common.protocol == WANCONFIG_PPP || + chan->common.protocol == WANCONFIG_CHDLC){ + + chan->common.prot_ptr = NULL; + wanpipe_generic_unregister(dev); + + }else if (chan->common.protocol == WANCONFIG_GENERIC){ + DEBUG_EVENT("%s:%s Protocol shutdown... \n", + card->devname, chan->if_name); + } +#endif + return 0; +} + +void protocol_recv(sdla_t *card, private_area_t *chan, netskb_t *skb) +{ + +#ifdef CONFIG_PRODUCT_WANPIPE_GENERIC + if (chan->common.protocol == WANCONFIG_PPP || + chan->common.protocol == WANCONFIG_CHDLC){ + wanpipe_generic_input(chan->common.dev, skb); + return 0; + } + +#if defined(__LINUX__) + if (chan->common.protocol == WANCONFIG_GENERIC){ + skb->protocol = htons(ETH_P_HDLC); + skb->dev = chan->common.dev; + wan_skb_reset_mac_header(skb); + netif_rx(skb); + return 0; + } +#endif + +#endif + +#if defined(__LINUX__) + skb->protocol = htons(ETH_P_IP); + skb->dev = chan->common.dev; + wan_skb_reset_mac_header(skb); + netif_rx(skb); +#else + DEBUG_EVENT("%s: Action not supported (IP)!\n", + card->devname); + wan_skb_free(skb); +#endif + + return; +} + + +/**SECTION************************************************************* + * + * TE1 Config Code + * + **********************************************************************/ +static int aft_global_chip_configuration(sdla_t *card, wandev_conf_t* conf) +{ + int err=0; + + err = aft_hwdev[card->wandev.card_type].aft_global_chip_config(card); + return err; +} + +static int aft_global_chip_disable(sdla_t *card) +{ + + aft_hwdev[card->wandev.card_type].aft_global_chip_unconfig(card); + + return 0; +} + +/*========================================================= + * aft_chip_configure + * + */ + +static int aft_chip_configure(sdla_t *card, wandev_conf_t* conf) +{ + + return aft_hwdev[card->wandev.card_type].aft_chip_config(card); +} + +static int aft_chip_unconfigure(sdla_t *card) +{ + u32 reg=0; + + AFT_FUNC_DEBUG(); + + wan_set_bit(CARD_DOWN,&card->wandev.critical); + + aft_hwdev[card->wandev.card_type].aft_chip_unconfig(card); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),&card->u.aft.lcfg_reg); + card->u.aft.lcfg_reg=reg; + return 0; +} + + +static int aft_dev_configure(sdla_t *card, private_area_t *chan, wanif_conf_t* conf) +{ + chan->logic_ch_num=-1; + + /* Channel definition section. If not channels defined + * return error */ + if (chan->time_slot_map == 0){ + DEBUG_EVENT("%s: Invalid Channel Selection 0x%lX\n", + card->devname,chan->time_slot_map); + return -EINVAL; + } + + + DEBUG_EVENT("%s: Active Ch Map :0x%08lX\n", + card->devname,chan->time_slot_map); + + + DEBUG_TEST("%s:%d: GOT Logic ch %ld Base 0x%X Size=0x%X\n", + __FUNCTION__,__LINE__,chan->logic_ch_num, + chan->fifo_base_addr, chan->fifo_size_code); + + + return aft_hwdev[card->wandev.card_type].aft_chan_config(card,chan); +} + +static void aft_dev_unconfigure(sdla_t *card, private_area_t *chan) +{ + aft_hwdev[card->wandev.card_type].aft_chan_unconfig(card,chan); + return ; +} + + +#define BIT_DEV_ADDR_CLEAR 0x600 + + + +/**SECTION************************************************************* + * + * TE1 Tx Functions + * DMA Chains + * + **********************************************************************/ + + +/*=============================================== + * aft_tx_dma_voice_handler + * + */ +static void aft_tx_dma_voice_handler(unsigned long data, int wdt, int reset) +{ + private_area_t *chan = (private_area_t *)data; + sdla_t *card = chan->card; + u32 reg,dma_descr,dma_status; + aft_dma_chain_t *dma_chain; + + if (wan_test_and_set_bit(TX_HANDLER_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + return; + } + + dma_chain = &chan->tx_dma_chain_table[0]; + + if (reset){ + wan_clear_bit(0,&dma_chain->init); + dma_descr=(chan->logic_ch_num<<4) + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + card->hw_iface.bus_write_4(card->hw,dma_descr,0); + goto aft_tx_dma_voice_handler_exit; + } + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (!wan_test_bit(0,&dma_chain->init)){ + goto aft_tx_dma_voice_handler_exit; + } + + dma_descr=(chan->logic_ch_num<<4) + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + /* If GO bit is set, then the current DMA chain + * is in process of being transmitted, thus + * all are busy */ + if (wan_test_bit(AFT_TXDMA_HI_GO_BIT,®)){ + goto aft_tx_dma_voice_handler_exit; + } + + dma_status = aft_txdma_hi_get_dma_status(reg); + + if (reg & AFT_TXDMA_HI_DMA_LENGTH_MASK){ + chan->errstats.Tx_dma_len_nonzero++; + chan->errstats.Tx_dma_errors++; + } + + if (dma_status){ + + DEBUG_TEST("%s:%s: Tx DMA Descriptor=0x%X\n", + card->devname,chan->if_name,reg); + + + /* Checking Tx DMA PCI error status. Has to be '0's */ + if (dma_status){ + + chan->errstats.Tx_pci_errors++; + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_M_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: Abort from Master: pci fatal error!\n", + card->devname,chan->if_name); + } + + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_T_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: Abort from Target: pci fatal error!\n", + card->devname,chan->if_name); + } + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_DS_TOUT,&dma_status)){ + DEBUG_TEST("%s:%s: Tx Warning: PCI Latency Timeout!\n", + card->devname,chan->if_name); + chan->errstats.Tx_pci_latency++; + goto aft_tx_dma_voice_handler_exit; + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_RETRY,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: 'Retry' exceeds maximum (64k): pci fatal error!\n", + card->devname,chan->if_name); + } + } + } + chan->if_stats.tx_errors++; + } + + + chan->opstats.Data_frames_Tx_count++; + chan->opstats.Data_bytes_Tx_count+=wan_skb_len(dma_chain->skb); + chan->if_stats.tx_packets++; + chan->if_stats.tx_bytes+=wan_skb_len(dma_chain->skb); + + wan_clear_bit(0,&dma_chain->init); + +aft_tx_dma_voice_handler_exit: + wan_clear_bit(TX_HANDLER_BUSY,&chan->dma_status); + + return; +} + + + +/*=============================================== + * aft_tx_dma_chain_handler + * + */ +static void aft_tx_dma_chain_handler(unsigned long data, int wdt, int reset) +{ + private_area_t *chan = (private_area_t *)data; + sdla_t *card = chan->card; + u32 reg,dma_descr; + aft_dma_chain_t *dma_chain; + + if (wan_test_and_set_bit(TX_HANDLER_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + return; + } + + dma_chain = &chan->tx_dma_chain_table[chan->tx_pending_chain_indx]; + + for (;;){ + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (!wan_test_bit(0,&dma_chain->init)){ + break; + } + + dma_descr=(chan->logic_ch_num<<4) + (chan->tx_pending_chain_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + /* If GO bit is set, then the current DMA chain + * is in process of being transmitted, thus + * all are busy */ + if (wan_test_bit(AFT_TXDMA_HI_GO_BIT,®)){ + break; + } + + if (!wan_test_bit(AFT_TXDMA_HI_INTR_DISABLE_BIT,®)){ + wan_clear_bit(TX_INTR_PENDING,&chan->dma_chain_status); + if (wdt){ + DEBUG_TEST("%s:%s TX WDT Timer got Interrtup pkt!\n", + card->devname,chan->if_name); + } + } + + + DEBUG_TEST("%s: TX DMA Handler Chain %d\n",chan->if_name,dma_chain->index); + + if (chan->hdlc_eng){ + if (dma_chain->skb){ + wan_skb_set_csum(dma_chain->skb, reg); + wan_skb_queue_tail(&chan->wp_tx_complete_list,dma_chain->skb); + dma_chain->skb=NULL; + } + }else{ + if (dma_chain->skb != chan->tx_idle_skb){ + + wan_skb_set_csum(dma_chain->skb, reg); + aft_tx_post_complete(chan->card,chan,dma_chain->skb); + + if (chan->channelized_cfg && !chan->hdlc_eng){ + /* Voice code uses the rx buffer to + * transmit! So put the rx buffer back + * into the rx queue */ + aft_init_requeue_free_skb(chan, dma_chain->skb); + }else{ + wan_skb_free(dma_chain->skb); + } + + dma_chain->skb=NULL; + } + } + + aft_tx_dma_chain_init(chan,dma_chain); + + if (chan->single_dma_chain){ + break; + } + + if (++chan->tx_pending_chain_indx >= MAX_AFT_DMA_CHAINS){ + chan->tx_pending_chain_indx=0; + } + + dma_chain = &chan->tx_dma_chain_table[chan->tx_pending_chain_indx]; + + } + + wan_clear_bit(TX_HANDLER_BUSY,&chan->dma_status); + + if (wan_skb_queue_len(&chan->wp_tx_complete_list)){ + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + } + + return; +} + +/*=============================================== + * aft_dma_chain_tx + * + */ +static int aft_dma_chain_tx(aft_dma_chain_t *dma_chain,private_area_t *chan, int intr,int fifo) +{ + +#define dma_descr dma_chain->dma_descr +#define reg dma_chain->reg +#define dma_ch_indx dma_chain->index +#define len_align dma_chain->len_align +#define card chan->card + + unsigned int len = dma_chain->dma_len; + unsigned int ss7_ctrl=0; + + dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + DEBUG_DMA("%s:%d: chan logic ch=%ld chain=%d dma_descr=0x%x set!\n", + __FUNCTION__,__LINE__,chan->logic_ch_num,dma_ch_indx,dma_descr); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + if (wan_test_bit(AFT_TXDMA_HI_GO_BIT,®)){ + DEBUG_EVENT("%s: Error: TxDMA GO Ready bit set on dma (chain=0x%X) Desc=0x%X Tx 0x%X\n", + card->devname,dma_descr,dma_ch_indx,reg); + /* Nothing we can do here, just reset + descriptor and keep going */ + card->hw_iface.bus_write_4(card->hw,dma_descr,0); + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + } + + dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_LO_DESCR_BASE_REG); + + /* Write the pointer of the data packet to the + * DMA address register */ + reg=dma_chain->dma_addr; + + + if (chan->cfg.ss7_enable){ + ss7_ctrl=wan_skb_csum(dma_chain->skb); + wan_skb_set_csum(dma_chain->skb,0); + if (ss7_ctrl&AFT_SS7_CTRL_LEN_MASK){ + len-=4; + len+=ss7_ctrl&AFT_SS7_CTRL_LEN_MASK; + } + if (!wan_test_bit(AFT_SS7_CTRL_TYPE_BIT,&ss7_ctrl)){ + /*FISU*/ + if (chan->cfg.ss7_mode == WANOPT_SS7_MODE_4096){ + len-=WANOPT_SS7_FISU_4096_SZ; + }else{ + len-=WANOPT_SS7_FISU_128_SZ; + } + }else{ + /*LSSU*/ + len-=chan->cfg.ss7_lssu_size; + } + } + + /* Set the 32bit alignment of the data length. + * Used to pad the tx packet to the 32 bit + * boundary */ + aft_txdma_lo_set_alignment(®,len); + + len_align=0; + if (len&0x03){ + len_align=1; + } + + DEBUG_DMA("%s: TXDMA_LO=0x%X PhyAddr=0x%X DmaDescr=0x%X Len=%i\n", + __FUNCTION__,reg,(int)dma_chain->dma_addr,dma_descr,len); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + reg=0; + + if (chan->cfg.ss7_enable){ + if (wan_test_bit(AFT_SS7_CTRL_TYPE_BIT,&ss7_ctrl)){ + wan_set_bit(AFT_TXDMA_HI_SS7_FISU_OR_LSSU_BIT,®); + }else{ + wan_clear_bit(AFT_TXDMA_HI_SS7_FISU_OR_LSSU_BIT,®); + } + if (wan_test_bit(AFT_SS7_CTRL_FORCE_BIT,&ss7_ctrl)){ + wan_set_bit(AFT_TXDMA_HI_SS7_FI_LS_FORCE_TX_BIT,®); + }else{ + wan_clear_bit(AFT_TXDMA_HI_SS7_FI_LS_FORCE_TX_BIT,®); + } + } + + aft_txdma_hi_set_dma_length(®,len,len_align); + + if (chan->single_dma_chain){ + wan_clear_bit(AFT_TXDMA_HI_LAST_DESC_BIT,®); + wan_clear_bit(AFT_TXDMA_HI_INTR_DISABLE_BIT,®); + + if (chan->channelized_cfg && !chan->hdlc_eng){ + wan_set_bit(AFT_TXDMA_HI_LAST_DESC_BIT,®); + } + }else{ + wan_set_bit(AFT_TXDMA_HI_LAST_DESC_BIT,®); + + if (intr){ + DEBUG_TEST("%s: Setting Interrupt on index=%d\n", + chan->if_name,dma_ch_indx); + wan_clear_bit(AFT_TXDMA_HI_INTR_DISABLE_BIT,®); + }else{ + wan_set_bit(AFT_TXDMA_HI_INTR_DISABLE_BIT,®); + } + } + + if (chan->hdlc_eng){ + /* Only enable the Frame Start/Stop on + * non-transparent hdlc configuration */ + wan_set_bit(AFT_TXDMA_HI_START_BIT,®); + wan_set_bit(AFT_TXDMA_HI_EOF_BIT,®); + }else{ + /* Used for transparent time slot + * synchronization */ + + if (chan->tslot_sync){ + wan_set_bit(AFT_TXDMA_HI_START_BIT,®); + } + } + + wan_set_bit(AFT_TXDMA_HI_GO_BIT,®); + if (fifo){ + /* Clear fifo command */ + wan_set_bit(AFT_TXDMA_HI_DMA_CMD_BIT,®); + } + + DEBUG_DMA("%s: TXDMA_HI=0x%X DmaDescr=0x%X Len=%d Intr=%d\n", + __FUNCTION__,reg,dma_descr,len,intr); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + +#if 1 + ++chan->tx_attempts; +#endif + + return 0; + +#undef dma_descr +#undef reg +#undef dma_ch_indx +#undef len_align +#undef card +} + +/*=============================================== + * aft_dma_chain_init + * + */ +static void aft_tx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *dma_chain) +{ + + if (dma_chain->dma_addr){ + chan->card->hw_iface.pci_unmap_dma(chan->card->hw, + dma_chain->dma_addr-dma_chain->dma_offset, + dma_chain->dma_map_len, + PCI_DMA_TODEVICE); + } + + if (dma_chain->skb){ + if (!chan->hdlc_eng){ + if (dma_chain->skb != chan->tx_idle_skb){ + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_init_requeue_free_skb(chan, dma_chain->skb); + }else{ + wan_skb_free(dma_chain->skb); + } + } + dma_chain->skb=NULL; + }else{ + wan_skb_free(dma_chain->skb); + dma_chain->skb=NULL; + } + } + + dma_chain->dma_addr=0; + dma_chain->dma_len=0; + dma_chain->dma_map_len=dma_chain->dma_len; + + wan_clear_bit(0,&dma_chain->init); +} + +static void aft_rx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *dma_chain) +{ + + if (dma_chain->dma_addr){ + chan->card->hw_iface.pci_unmap_dma(chan->card->hw, + dma_chain->dma_addr-dma_chain->dma_offset, + dma_chain->dma_map_len, + PCI_DMA_FROMDEVICE); + } + + if (dma_chain->skb){ + aft_init_requeue_free_skb(chan,dma_chain->skb); + dma_chain->skb=NULL; + } + + dma_chain->dma_addr=0; + dma_chain->dma_len=0; + dma_chain->dma_map_len=0; + + wan_clear_bit(0,&dma_chain->init); +} + + + +static int aft_dma_voice_tx(sdla_t *card, private_area_t *chan) +{ + int err=0; + aft_dma_chain_t *dma_chain; + u32 reg, dma_ram_desc; + + if (wan_test_and_set_bit(TX_DMA_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + + return -EBUSY; + } + + dma_chain = &chan->tx_dma_chain_table[0]; + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (wan_test_and_set_bit(0,&dma_chain->init)){ + err=-EBUSY; + goto aft_dma_voice_tx_exit; + } + + if (!dma_chain->skb){ + unsigned char *buf; + + /* Take already preallocated buffer from rx queue. + * We are only using a single buffer for rx and tx */ + dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!dma_chain->skb){ + DEBUG_EVENT("%s: Warning Tx chain = %d: no free tx bufs\n", + chan->if_name,dma_chain->index); + wan_clear_bit(0,&dma_chain->init); + err=-EINVAL; + goto aft_dma_voice_tx_exit; + } + + wan_skb_init(dma_chain->skb,16); + wan_skb_trim(dma_chain->skb,0); + + /*NC: We must set the initial value of the + * frist DMA TX transfer to 2*MTU. This is + * to avoid potential Tx FIFO underrun. + * + * This is equivalent of transmitting twice + * very fist time. */ + + + buf=wan_skb_put(dma_chain->skb,chan->mtu*2); + memset(buf,chan->idle_flag,chan->mtu*2); + + dma_chain->dma_addr = card->hw_iface.pci_map_dma(card->hw, + wan_skb_data(dma_chain->skb), + chan->dma_mru, + PCI_DMA_TODEVICE); + + if (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) { + dma_chain->dma_offset = + AFT_TDMV_BUF_MASK - (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) + 1; + + dma_chain->dma_virt = wan_skb_data(dma_chain->skb) + dma_chain->dma_offset; + dma_chain->dma_addr += dma_chain->dma_offset; + + } else { + dma_chain->dma_offset=0; + dma_chain->dma_virt = wan_skb_data(dma_chain->skb); + } + + dma_chain->dma_len = wan_skb_len(dma_chain->skb); + dma_chain->dma_map_len=chan->dma_mru; + + } + + + dma_ram_desc=chan->logic_ch_num*4 + + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + aft_dmachain_set_tx_dma_addr(®,1); + card->hw_iface.bus_write_4(card->hw,dma_ram_desc,reg); + + /* We set inital TX DMA with FIFO Reset option. This funciton + * will ONLY run once in TDM mode. After the inital TX the + * DMA Reload will be used to tx the Voice frame */ + err=aft_dma_chain_tx(dma_chain,chan,1,1); + if (err){ + DEBUG_EVENT("%s: Tx dma chain %d overrun error: should never happen!\n", + chan->if_name,dma_chain->index); + + /* Drop the tx packet here */ + aft_tx_dma_chain_init(chan,dma_chain); + chan->if_stats.tx_errors++; + err=-EINVAL; + goto aft_dma_voice_tx_exit; + } + +aft_dma_voice_tx_exit: + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + + return 0; +} + +/*=============================================== + * aft_dma_tx + * + */ +static int aft_dma_tx (sdla_t *card,private_area_t *chan) +{ + int err=0, intr=0, cnt=0; + aft_dma_chain_t *dma_chain; + netskb_t *skb=NULL; + + if (chan->channelized_cfg && !chan->hdlc_eng){ + return aft_dma_voice_tx(card,chan); + } + + if (wan_test_and_set_bit(TX_DMA_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + + return -EBUSY; + } + + if (chan->tx_chain_indx >= MAX_AFT_DMA_CHAINS){ + DEBUG_EVENT("%s: MAJOR ERROR: TE1 Tx: Dma tx chain = %d\n", + chan->if_name,chan->tx_chain_indx); + return -EBUSY; + } + + + /* The cnt is not used, its used only as a + * sanity check. The code below should break + * out of the loop before MAX_TX_BUF runs out! */ + for (cnt=0;cnttx_dma_chain_table[chan->tx_chain_indx]; + + /* FIXME: Reset TX Watchdog */ + /* aft_reset_tx_watchdog(card); */ + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (wan_test_and_set_bit(0,&dma_chain->init)){ + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + break; + } + + if(!chan->lip_atm){ + skb=wan_skb_dequeue(&chan->wp_tx_pending_list); + }else{ + skb=atm_tx_skb_dequeue(&chan->wp_tx_pending_list, chan->tx_idle_skb, chan->if_name); + } + + if (!skb){ + if (!chan->hdlc_eng){ + + skb=chan->tx_idle_skb; + if (!skb){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical Error: Transparent tx no skb!\n", + chan->if_name); + } + break; + } + + ++chan->if_stats.tx_carrier_errors; + }else{ + wan_clear_bit(0,&dma_chain->init); + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + break; + } + } + + if ((unsigned long)wan_skb_data(skb) & 0x03){ + + err=aft_realign_skb_pkt(chan,skb); + if (err){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Tx Error: Non Aligned packet %p: dropping...\n", + chan->if_name,wan_skb_data(skb)); + } + wan_skb_free(skb); + aft_tx_dma_chain_init(chan,dma_chain); + chan->if_stats.tx_errors++; + chan->opstats.Tx_Data_discard_lgth_err_count++; + continue; + } + } + + + if (!chan->hdlc_eng && (wan_skb_len(skb)%4)){ + + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Tx Error: Tx Length %i not 32bit aligned: dropping...\n", + chan->if_name,wan_skb_len(skb)); + } + wan_skb_free(skb); + aft_tx_dma_chain_init(chan,dma_chain); + chan->if_stats.tx_errors++; + chan->opstats.Tx_Data_discard_lgth_err_count++; + continue; + } + + dma_chain->skb=skb; + + dma_chain->dma_addr = card->hw_iface.pci_map_dma(card->hw, + wan_skb_data(dma_chain->skb), + wan_skb_len(dma_chain->skb), + PCI_DMA_TODEVICE); + + dma_chain->dma_len = wan_skb_len(dma_chain->skb); + dma_chain->dma_map_len=dma_chain->dma_len; + dma_chain->dma_offset=0; + + + DEBUG_TEST("%s: DMA Chain %d: Cur=%d Pend=%d\n", + chan->if_name,dma_chain->index, + chan->tx_chain_indx,chan->tx_pending_chain_indx); + + intr=0; + if (!wan_test_bit(TX_INTR_PENDING,&chan->dma_chain_status)){ + int pending_indx=chan->tx_pending_chain_indx; + if (chan->tx_chain_indx >= pending_indx){ + intr = ((MAX_AFT_DMA_CHAINS-(chan->tx_chain_indx - + pending_indx))<=2); + }else{ + intr = ((pending_indx - chan->tx_chain_indx)<=2); + } + + if (intr){ + DEBUG_TEST("%s: Setting tx interrupt on chain=%d\n", + chan->if_name,dma_chain->index); + wan_set_bit(TX_INTR_PENDING,&chan->dma_chain_status); + } + } + + + err=aft_dma_chain_tx(dma_chain,chan,intr,0); + if (err){ + DEBUG_EVENT("%s: Tx dma chain %d overrun error: should never happen!\n", + chan->if_name,dma_chain->index); + + +#if 0 + aft_list_tx_descriptors(chan); + aft_critical_shutdown(card); + break; +#endif + + /* Drop the tx packet here */ + aft_tx_dma_chain_init(chan,dma_chain); + chan->if_stats.tx_errors++; + break; + } + + if (skb){ + wan_capture_trace_packet(card, &chan->trace_info, skb, TRC_OUTGOING_FRM); + } + + if (chan->single_dma_chain){ + break; + }else{ + if (++chan->tx_chain_indx >= MAX_AFT_DMA_CHAINS){ + chan->tx_chain_indx=0; + } + } + } + + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + + return 0; +} + + + +/**SECTION************************************************************* + * + * TE1 Rx Functions + * DMA Chains + * + **********************************************************************/ + +static int aft_dma_chain_rx(aft_dma_chain_t *dma_chain, private_area_t *chan, int intr, int fifo) +{ +#define dma_descr dma_chain->dma_descr +#define reg dma_chain->reg +#define len dma_chain->dma_len +#define dma_ch_indx dma_chain->index +#define len_align dma_chain->len_align +#define card chan->card + + /* Write the pointer of the data packet to the + * DMA address register */ + reg=dma_chain->dma_addr; + + /* Set the 32bit alignment of the data length. + * Since we are setting up for rx, set this value + * to Zero */ + aft_rxdma_lo_set_alignment(®,0); + + dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_LO_DESCR_BASE_REG); + + DEBUG_DMA("%s: RxDMA_LO(%ld) = 0x%X, DmaDescr=0x%X\n", + __FUNCTION__,chan->logic_ch_num,reg,dma_descr); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + reg =0; + + if (chan->single_dma_chain){ + wan_clear_bit(AFT_RXDMA_HI_LAST_DESC_BIT,®); + wan_clear_bit(AFT_RXDMA_HI_INTR_DISABLE_BIT,®); + + if (chan->channelized_cfg && !chan->hdlc_eng){ + wan_set_bit(AFT_RXDMA_HI_LAST_DESC_BIT,®); + } + + }else{ + wan_set_bit(AFT_RXDMA_HI_LAST_DESC_BIT,®); + +#if AFT_IFT_INTR_ENABLE + wan_set_bit(AFT_RXDMA_HI_IFT_INTR_ENB_BIT,®); +#else + wan_clear_bit(AFT_RXDMA_HI_IFT_INTR_ENB_BIT,®); +#endif + + if (intr){ + DEBUG_TEST("%s: Setting Rx Interrupt on index=%d\n", + chan->if_name,dma_ch_indx); + wan_clear_bit(AFT_RXDMA_HI_INTR_DISABLE_BIT,®); + }else{ + wan_set_bit(AFT_RXDMA_HI_INTR_DISABLE_BIT,®); + } + } + + if (chan->hdlc_eng){ + aft_rxdma_hi_set_dma_length(®,chan->dma_mru,1); + }else{ + aft_rxdma_hi_set_dma_length(®,chan->mru,0); + } + + wan_set_bit(AFT_RXDMA_HI_GO_BIT,®); + if (fifo){ + wan_set_bit(AFT_RXDMA_HI_DMA_CMD_BIT,®); + } + + DEBUG_DMA("%s: RXDMA_HI(%ld) = 0x%X, DmaDescr=0x%X\n", + __FUNCTION__,chan->logic_ch_num,reg,dma_descr); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + return 0; + +#undef dma_descr +#undef reg +#undef len +#undef dma_ch_indx +#undef len_align +#undef card +} + +static int aft_dma_voice_rx(sdla_t *card, private_area_t *chan) +{ + int err=0; + aft_dma_chain_t *dma_chain; + u32 reg, dma_ram_desc; + + if (wan_test_and_set_bit(RX_DMA_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + return -EBUSY; + } + + dma_chain = &chan->rx_dma_chain_table[0]; + + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (wan_test_and_set_bit(0,&dma_chain->init)){ + DEBUG_TEST("%s: Warning: %s():%d dma chain busy %d!\n", + card->devname, __FUNCTION__, __LINE__, + dma_chain->index); + err=-EBUSY; + goto aft_dma_single_chain_rx_exit; + } + + /* This will only be done on the first time. The dma_chain + * skb will be re-used all the time, thus no need for + * rx_free_list any more */ + if (!dma_chain->skb){ + dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!dma_chain->skb){ + DEBUG_EVENT("%s: Warning Rx Voice chain = %d: no free rx bufs\n", + chan->if_name,dma_chain->index); + wan_clear_bit(0,&dma_chain->init); + err=-EINVAL; + goto aft_dma_single_chain_rx_exit; + } + + wan_skb_init(dma_chain->skb,16); + wan_skb_trim(dma_chain->skb,0); + +#if defined(__LINUX__) + dma_chain->dma_addr = card->hw_iface.pci_map_dma(card->hw, + wan_skb_tail(dma_chain->skb), + chan->dma_mru, + PCI_DMA_FROMDEVICE); + + if (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) { + dma_chain->dma_offset = + AFT_TDMV_BUF_MASK - (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) + 1; + + dma_chain->dma_virt = wan_skb_tail(dma_chain->skb) + dma_chain->dma_offset; + dma_chain->dma_addr += dma_chain->dma_offset; + + } else { + dma_chain->dma_offset=0; + dma_chain->dma_virt = wan_skb_tail(dma_chain->skb); + } + + dma_chain->dma_len = chan->dma_mru-dma_chain->dma_offset; + dma_chain->dma_map_len=dma_chain->dma_len; + + DEBUG_TEST("%s: RXDMA PHY = 0x%08X VIRT = %p \n", + chan->if_name, + dma_chain->dma_addr,wan_skb_tail(dma_chain->skb)+dma_chain->dma_offset); +#else + dma_chain->dma_addr = + virt_to_phys(wan_skb_tail(dma_chain->skb)); + + if (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) { + dma_chain->dma_offset = + AFT_TDMV_BUF_MASK - + (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) + 1; + dma_chain->dma_virt = wan_skb_tail(dma_chain->skb) + dma_chain->dma_offset; + dma_chain->dma_addr = virt_to_phys(wan_skb_tail(dma_chain->dma_virt)); + } else { + dma_chain->dma_offset=0; + dma_chain->dma_virt = wan_skb_tail(dma_chain->skb); + } + + dma_chain->dma_len = chan->dma_mru; + dma_chain->dma_map_len=dma_chain->dma_len; + +#endif + }else{ + wan_skb_init(dma_chain->skb,16); + wan_skb_trim(dma_chain->skb,0); + } + + dma_ram_desc=chan->logic_ch_num*4 + + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + aft_dmachain_set_rx_dma_addr(®,1); + card->hw_iface.bus_write_4(card->hw,dma_ram_desc,reg); + + err=aft_dma_chain_rx(dma_chain,chan,1,1); + if (err){ + DEBUG_EVENT("%s: Rx dma chain %d overrun error: should never happen!\n", + chan->if_name,dma_chain->index); + aft_rx_dma_chain_init(chan,dma_chain); + chan->if_stats.rx_errors++; + } + +aft_dma_single_chain_rx_exit: + + wan_clear_bit(RX_DMA_BUSY,&chan->dma_status); + return err; +} + + +static int aft_dma_rx(sdla_t *card, private_area_t *chan) +{ + int err=0, intr=0; + aft_dma_chain_t *dma_chain; + int cur_dma_ptr, i,max_dma_cnt,free_queue_len; + u32 reg, dma_ram_desc; + + + if (chan->channelized_cfg && !chan->hdlc_eng){ + return aft_dma_voice_rx(card,chan); + } + + if (wan_test_and_set_bit(RX_DMA_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + return -EBUSY; + } + + free_queue_len=wan_skb_queue_len(&chan->wp_rx_free_list); + if (!chan->single_dma_chain && + free_queue_len < MAX_AFT_DMA_CHAINS){ + aft_free_rx_complete_list(chan); + free_queue_len=wan_skb_queue_len(&chan->wp_rx_free_list); + if (free_queue_len < MAX_AFT_DMA_CHAINS){ + DEBUG_EVENT("%s: %s() CRITICAL ERROR: No free rx buffers\n", + card->devname,__FUNCTION__); + goto te1rx_skip; + } + } + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + +#if 0 + aft_chain_history(chan,chan->rx_chain_indx, cur_dma_ptr, chan->rx_pending_chain_indx,1); +#endif + max_dma_cnt = MAX_AFT_DMA_CHAINS; + + if (!chan->single_dma_chain && + free_queue_len < max_dma_cnt){ + max_dma_cnt = free_queue_len; + } + + + DEBUG_TEST("%s: DMA RX: CBoardPtr=%d Driver=%d MaxDMA=%d\n", + card->devname,cur_dma_ptr,chan->rx_chain_indx,max_dma_cnt); + + for (i=0;irx_dma_chain_table[chan->rx_chain_indx]; + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (wan_test_and_set_bit(0,&dma_chain->init)){ + DEBUG_TEST("%s: Warning: %s():%d dma chain busy %d!\n", + card->devname, __FUNCTION__, __LINE__, + dma_chain->index); + + err=-EBUSY; + break; + } + + dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!dma_chain->skb){ + /* If this ever happends, it means that wp_bh is stuck for some + * reason, thus start using the completed buffers, thus + * overflow the data */ + dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_complete_list); + if (dma_chain->skb) { + chan->if_stats.rx_dropped++; + wan_skb_init(dma_chain->skb,16); + wan_skb_trim(dma_chain->skb,0); + }else{ + DEBUG_EVENT("%s: Critical Rx chain = %d: no free rx bufs (Free=%i Comp=%i)\n", + chan->if_name,dma_chain->index, + wan_skb_queue_len(&chan->wp_rx_free_list), + wan_skb_queue_len(&chan->wp_rx_complete_list)); + wan_clear_bit(0,&dma_chain->init); + + aft_critical_shutdown(card); + err=-EINVAL; + break; + } + + } + + dma_chain->dma_addr = card->hw_iface.pci_map_dma(card->hw, + wan_skb_tail(dma_chain->skb), + chan->dma_mru, + PCI_DMA_FROMDEVICE); + + dma_chain->dma_len = chan->dma_mru; + dma_chain->dma_map_len=dma_chain->dma_len; + dma_chain->dma_offset=0; + + intr=0; + if (!wan_test_bit(RX_INTR_PENDING,&chan->dma_chain_status)){ + + free_queue_len--; + + if (free_queue_len <= 2){ + DEBUG_TEST("%s: DBG: Setting intr queue size low\n", + card->devname); + intr=1; + }else{ + if (chan->rx_chain_indx >= cur_dma_ptr){ + intr = ((MAX_AFT_DMA_CHAINS - + (chan->rx_chain_indx-cur_dma_ptr)) <=4); + }else{ + intr = ((cur_dma_ptr - chan->rx_chain_indx)<=4); + } + } + + if (intr){ + DEBUG_TEST("%s: Setting Rx interrupt on chain=%d\n", + chan->if_name,dma_chain->index); + wan_set_bit(RX_INTR_PENDING,&chan->dma_chain_status); + } + } + + DEBUG_TEST("%s: Setting Buffer on Rx Chain = %d Intr=%d\n", + chan->if_name,dma_chain->index, intr); + + err=aft_dma_chain_rx(dma_chain,chan,intr,0); + if (err){ + DEBUG_EVENT("%s: Rx dma chain %d overrun error: should never happen!\n", + chan->if_name,dma_chain->index); + aft_rx_dma_chain_init(chan,dma_chain); + chan->if_stats.rx_errors++; + break; + } + + if (chan->single_dma_chain){ + break; + }else{ + if (++chan->rx_chain_indx >= MAX_AFT_DMA_CHAINS){ + chan->rx_chain_indx=0; + } + } + } + +#if 0 + aft_chain_history(chan,chan->rx_chain_indx, cur_dma_ptr, chan->rx_pending_chain_indx,2); + + if (chan->rx_chain_indx == cur_dma_ptr && + chan->rx_pending_chain_indx == cur_dma_ptr && + cur_dma_ptr != 0){ + DEBUG_EVENT("%s :Location 1 Listing Descr!\n", + chan->if_name); + aft_list_descriptors(chan); + } +#endif + aft_rx_cur_go_test(chan); + +te1rx_skip: + + wan_clear_bit(RX_DMA_BUSY,&chan->dma_status); + + return err; +} + +/*=============================================== + * aft_rx_dma_chain_handler + * + */ +/*N1*/ +static int aft_rx_dma_chain_handler(private_area_t *chan, int reset) +{ + sdla_t *card = chan->card; + u32 reg,dma_descr; + wp_rx_element_t *rx_el; + aft_dma_chain_t *dma_chain; + int i,max_dma_cnt, cur_dma_ptr; + int rx_data_available=0; + u32 dma_ram_desc; + + if (wan_test_and_set_bit(RX_HANDLER_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + return rx_data_available; + } + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + + max_dma_cnt = MAX_AFT_DMA_CHAINS; + + DEBUG_TEST("%s: DMA RX: CBoardPtr=%d Driver=%d MaxDMA=%d\n", + card->devname, + cur_dma_ptr, + chan->rx_chain_indx,max_dma_cnt); + +#if 0 + aft_chain_history(chan,chan->rx_chain_indx, cur_dma_ptr, chan->rx_pending_chain_indx,3); +#endif + + + for (i=0;irx_dma_chain_table[chan->rx_pending_chain_indx]; + + if (i>0 && chan->rx_pending_chain_indx == cur_dma_ptr){ + break; + } + + if (!dma_chain){ + DEBUG_EVENT("%s:%d Assertion Error !!!!\n", + __FUNCTION__,__LINE__); + break; + } + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (!wan_test_bit(0,&dma_chain->init)){ + DEBUG_TEST("%s: Warning (%s) Pending chain %d empty!\n", + chan->if_name,__FUNCTION__,dma_chain->index); + + break; + } + + dma_descr=(chan->logic_ch_num<<4) + (dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + /* If GO bit is set, then the current DMA chain + * is in process of being transmitted, thus + * all are busy */ + if (wan_test_bit(AFT_RXDMA_HI_GO_BIT,®)){ + + if (wan_test_bit(WP_FIFO_ERROR_BIT, &chan->pkt_error)){ + break; + } + +#if 0 + if (chan->single_dma_chain){ + DEBUG_EVENT("%s: CRITICAL (%s) Pending chain %d Go bit still set!\n", + chan->if_name,__FUNCTION__,dma_chain->index); + ++chan->if_stats.rx_errors; + }else{ + DEBUG_TEST("%s: Warning (%s) Pending chain %d Go bit still set!\n", + chan->if_name,__FUNCTION__,dma_chain->index); + } +#endif + break; + } + + if (!wan_test_bit(AFT_RXDMA_HI_INTR_DISABLE_BIT,®)){ + wan_clear_bit(RX_INTR_PENDING,&chan->dma_chain_status); + } + + card->hw_iface.pci_unmap_dma(card->hw, + dma_chain->dma_addr-dma_chain->dma_offset, + dma_chain->dma_map_len, + PCI_DMA_FROMDEVICE); + + if (sizeof(wp_rx_element_t) > wan_skb_headroom(dma_chain->skb)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Rx error: rx_el=%u > max head room=%u\n", + chan->if_name, + (u32)sizeof(wp_rx_element_t), + (u32)wan_skb_headroom(dma_chain->skb)); + } + + aft_init_requeue_free_skb(chan, dma_chain->skb); + ++chan->if_stats.rx_errors; + goto rx_hndlr_skip_rx; + }else{ + rx_el=(wp_rx_element_t *)wan_skb_push(dma_chain->skb, + sizeof(wp_rx_element_t)); + memset(rx_el,0,sizeof(wp_rx_element_t)); + } +#if 0 + chan->if_stats.rx_frame_errors++; +#endif + + /* Reading Rx DMA descriptor information */ + dma_descr=(chan->logic_ch_num<<4) +(dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_LO_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr, &rx_el->align); + rx_el->align&=AFT_RXDMA_LO_ALIGN_MASK; + + dma_descr=(chan->logic_ch_num<<4) +(dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr, &rx_el->reg); + + rx_el->pkt_error= dma_chain->pkt_error; + rx_el->dma_addr = dma_chain->dma_addr; + + wan_skb_queue_tail(&chan->wp_rx_complete_list,dma_chain->skb); + rx_data_available=1; + + DEBUG_TEST("%s: RxInt Pending chain %d Rxlist=%d LO:0x%X HI:0x%X Data=0x%X Len=%d!\n", + chan->if_name,dma_chain->index, + wan_skb_queue_len(&chan->wp_rx_complete_list), + rx_el->align,rx_el->reg, + (*(unsigned char*)wan_skb_data(dma_chain->skb)), + wan_skb_len(dma_chain->skb)); + +rx_hndlr_skip_rx: + dma_chain->skb=NULL; + dma_chain->dma_addr=0; + dma_chain->dma_len=0; + dma_chain->dma_map_len=dma_chain->dma_len; + dma_chain->pkt_error=0; + wan_clear_bit(0,&dma_chain->init); + + if (chan->single_dma_chain){ + break; + } + + if (++chan->rx_pending_chain_indx >= MAX_AFT_DMA_CHAINS){ + chan->rx_pending_chain_indx=0; + } + } + + if (reset){ + goto reset_skip_rx_setup; + } + + aft_dma_rx(card,chan); + + + if (wan_skb_queue_len(&chan->wp_rx_complete_list)){ + DEBUG_TEST("%s: Rx Queued list triggering\n",chan->if_name); + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + } + +reset_skip_rx_setup: + + wan_clear_bit(RX_HANDLER_BUSY,&chan->dma_status); + + + return rx_data_available; +} + +static int aft_dma_rx_complete(sdla_t *card, private_area_t *chan, int reset) +{ + if (chan->cfg.ss7_enable){ + aft_clear_ss7_force_rx(card,chan); + } + return aft_rx_dma_chain_handler(chan,reset); +} + +/*=============================================== + * TE1 DMA Chains Utility Funcitons + * + */ + + +static void aft_index_tx_rx_dma_chains(private_area_t *chan) +{ + int i; + + for (i=0;itx_dma_chain_table[i].index=i; + chan->rx_dma_chain_table[i].index=i; + } +} + + +static void aft_init_tx_rx_dma_descr(private_area_t *chan) +{ + int i; + u32 reg=0; + sdla_t *card=chan->card; + unsigned long tx_dma_descr,rx_dma_descr; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + if (chan->single_dma_chain){ + dma_cnt=1; + } + + for (i=0;ilogic_ch_num<<4) + + (i*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + rx_dma_descr=(chan->logic_ch_num<<4) + + (i*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_write_4(card->hw,tx_dma_descr,reg); + card->hw_iface.bus_write_4(card->hw,rx_dma_descr,reg); + + aft_tx_dma_chain_init(chan,&chan->tx_dma_chain_table[i]); + aft_rx_dma_chain_init(chan,&chan->rx_dma_chain_table[i]); + } +} + +static void aft_free_rx_complete_list(private_area_t *chan) +{ + void *skb; + + while((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ + DEBUG_TEST("%s: aft_free_rx_complete_list dropped\n", + chan->if_name); + chan->if_stats.rx_dropped++; + aft_init_requeue_free_skb(chan, skb); + } +} + +static void aft_rx_cur_go_test(private_area_t *chan) +{ +#if 0 + u32 reg,cur_dma_ptr; + sdla_t *card=chan->card; + aft_dma_chain_t *dma_chain; + u32 dma_descr; + int i; + u32 dma_ram_desc; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + + dma_descr=(chan->logic_ch_num<<4) +(cur_dma_ptr*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + if (!wan_test_bit(AFT_RXDMA_HI_GO_BIT,®)){ + DEBUG_EVENT("%s: CRITICAL Cur =%d not Got bit set!\n", + chan->if_name, + cur_dma_ptr); + + + aft_list_descriptors(chan); + } +#endif +} + + +#if 0 +static void aft_list_descriptors(private_area_t *chan) +{ + u32 reg,cur_dma_ptr,lo_reg; + sdla_t *card=chan->card; + aft_dma_chain_t *dma_chain; + u32 dma_descr; + int i; + u32 dma_ram_desc; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + + DEBUG_TEST("%s: RX Chain DMA List: End=%d Begin=%d Cur=%d \n", + chan->if_name, + chan->rx_chain_indx, + chan->rx_pending_chain_indx, + cur_dma_ptr); + + if (chan->single_dma_chain){ + dma_cnt=1; + } + + for (i=0;irx_dma_chain_table[i]; + if (!dma_chain){ + DEBUG_EVENT("%s:%d Assertion Error !!!!\n", + __FUNCTION__,__LINE__); + break; + } + + dma_descr=(chan->logic_ch_num<<4) +(dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + dma_descr=(chan->logic_ch_num<<4) +(dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_LO_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,&lo_reg); + + DEBUG_EVENT("%s: RX DMA=%d : Go=%u Intr=%u Used=%lu A=0%X R=0x%X L=0x%08X C=%i\n", + chan->if_name, + dma_chain->index, + wan_test_bit(AFT_RXDMA_HI_GO_BIT,®), + !wan_test_bit(AFT_RXDMA_HI_INTR_DISABLE_BIT,®), + dma_chain->init,dma_descr,reg,lo_reg,(lo_reg&0x1FF)/128); + } +} +#endif + +#if 0 +static void aft_list_tx_descriptors(private_area_t *chan) +{ + u32 reg,cur_dma_ptr,lo_reg; + sdla_t *card=chan->card; + aft_dma_chain_t *dma_chain; + u32 dma_descr; + int i; + u32 dma_ram_desc; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_tx_dma_addr(reg); + + + DEBUG_TEST("%s: TX Chain DMA List: Cur(End)=%d, Pend(Begin)=%d HWCur=%d\n", + chan->if_name, + chan->tx_chain_indx, + chan->tx_pending_chain_indx, + cur_dma_ptr); + + if (chan->single_dma_chain){ + dma_cnt=1; + } + + for (i=0;itx_dma_chain_table[i]; + if (!dma_chain){ + DEBUG_EVENT("%s:%d Assertion Error !!!!\n", + __FUNCTION__,__LINE__); + break; + } + + dma_descr=(chan->logic_ch_num<<4) + + (dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + dma_descr=(chan->logic_ch_num<<4) + + (dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_LO_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,&lo_reg); + + DEBUG_EVENT("%s: TX DMA=%d : Go=%u Intr=%u Used=%lu A=0%X R=0x%08X L=0x%08X C=%i\n", + chan->if_name, + dma_chain->index, + wan_test_bit(AFT_TXDMA_HI_GO_BIT,®), + wan_test_bit(AFT_TXDMA_HI_INTR_DISABLE_BIT,®) ? 0:1, + dma_chain->init, + dma_descr, + reg,lo_reg,(lo_reg&0x1FF)/128); + + } +} +#endif + +#if 0 +static void aft_list_dma_chain_regs(sdla_t *card) +{ + u32 reg; + int i; + u32 dma_ram_desc; + + for (i=0; iu.aft.num_of_time_slots;i++){ + + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + + DEBUG_EVENT("%s: DMA CHAIN: %i: 0x%08X\n", + card->devname,i,reg); + + } +} +#endif + + +static void aft_free_rx_descriptors(private_area_t *chan) +{ + u32 reg; + sdla_t *card=chan->card; + aft_dma_chain_t *dma_chain; + u32 dma_descr; + int i; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + if (chan->single_dma_chain){ + dma_cnt=1; + } + + for (i=0;irx_dma_chain_table[i]; + if (!dma_chain){ + DEBUG_EVENT("%s:%d Assertion Error !!!!\n", + __FUNCTION__,__LINE__); + break; + } + + dma_descr=(chan->logic_ch_num<<4) + + (dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + DEBUG_TEST("%s:%s: Rx: Freeing Descripors Ch=%ld Desc=0x%X\n", + card->devname,chan->if_name,chan->logic_ch_num,dma_descr); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + /* If GO bit is set, then the current DMA chain + * is in process of being transmitted, thus + * all are busy */ + reg=0; + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + card->hw_iface.pci_unmap_dma(card->hw, + dma_chain->dma_addr-dma_chain->dma_offset, + dma_chain->dma_map_len, + PCI_DMA_FROMDEVICE); + + if (dma_chain->skb){ + aft_init_requeue_free_skb(chan, dma_chain->skb); + } + + dma_chain->skb=NULL; + dma_chain->dma_addr=0; + dma_chain->dma_len=0; + dma_chain->dma_map_len=dma_chain->dma_len; + dma_chain->pkt_error=0; + wan_clear_bit(0,&dma_chain->init); + } + +} + +static void aft_reset_rx_chain_cnt(private_area_t *chan) +{ + u32 dma_ram_desc,reg,cur_dma_ptr; + sdla_t *card=chan->card; + + dma_ram_desc=chan->logic_ch_num*4+ + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + chan->rx_pending_chain_indx = chan->rx_chain_indx = cur_dma_ptr; + DEBUG_TEST("%s: Setting Rx Index to %d\n", + chan->if_name,cur_dma_ptr); + +} + +static void aft_reset_tx_chain_cnt(private_area_t *chan) +{ + u32 dma_ram_desc,reg,cur_dma_ptr; + sdla_t *card=chan->card; + + dma_ram_desc=chan->logic_ch_num*4+ + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_tx_dma_addr(reg); + chan->tx_pending_chain_indx = chan->tx_chain_indx = cur_dma_ptr; + DEBUG_TEST("%s: Setting Tx Index to %d\n", + chan->if_name,cur_dma_ptr); + +} + + + +static void aft_free_tx_descriptors(private_area_t *chan) +{ + u32 reg,dma_descr; + sdla_t *card=chan->card; + aft_dma_chain_t *dma_chain; + int i; + void *skb; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + if (chan->single_dma_chain){ + dma_cnt=1; + } + + DEBUG_TEST("%s:%s: Tx: Freeing Descripors\n",card->devname,chan->if_name); + + for (i=0;itx_dma_chain_table[i]; + if (!dma_chain){ + DEBUG_EVENT("%s:%d Assertion Error !!!!\n", + __FUNCTION__,__LINE__); + break; + } + + dma_descr=(chan->logic_ch_num<<4) +(dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + DEBUG_TEST("%s:%s: Tx: Freeing Descripors Ch=%ld Desc=0x%X\n", + card->devname,chan->if_name,chan->logic_ch_num,dma_descr); + reg=0; + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + aft_tx_dma_chain_init(chan, dma_chain); + } + + chan->tx_chain_indx = chan->tx_pending_chain_indx; + + while((skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ + wan_skb_free(skb); + } +} + + +/*===================================================== + * Chanalization/Logic Channel utilites + * + */ +void aft_free_logical_channel_num (sdla_t *card, int logic_ch) +{ + wan_clear_bit (logic_ch,&card->u.aft.logic_ch_map); + card->u.aft.dev_to_ch_map[logic_ch]=NULL; + + if (logic_ch >= card->u.aft.top_logic_ch){ + int i; + + card->u.aft.top_logic_ch=AFT_DEFLT_ACTIVE_CH; + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (card->u.aft.dev_to_ch_map[i]){ + card->u.aft.top_logic_ch=i; + } + } + + + aft_dma_max_logic_ch(card); + } + +} + +void aft_dma_max_logic_ch(sdla_t *card) +{ + u32 reg; + + DEBUG_TEST("%s: Maximum Logic Ch set to %d \n", + card->devname,card->u.aft.top_logic_ch); + + reg=0; + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + aft_dmactrl_set_max_logic_ch(®,card->u.aft.top_logic_ch); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); +} + +static int aft_tslot_sync_ctrl(sdla_t *card, private_area_t *chan, int mode) +{ + u32 dma_ram_reg,reg; + + if (chan->hdlc_eng){ + return 0; + } + + + dma_ram_reg=AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + dma_ram_reg+=(chan->logic_ch_num*4); + + card->hw_iface.bus_read_4(card->hw, dma_ram_reg, ®); + + if (mode){ + wan_set_bit(AFT_DMACHAIN_RX_SYNC_BIT,®); + }else{ + wan_clear_bit(AFT_DMACHAIN_RX_SYNC_BIT,®); + } + + card->hw_iface.bus_write_4(card->hw, dma_ram_reg, reg); + + return 0; +} + + + +static int aft_read_security(sdla_t *card) +{ + int adptr_security; + wan_smp_flag_t flags,smp_flags; + + if (card->adptr_subtype == AFT_SUBTYPE_SHARK){ + /* Shark cards are always channelized */ + card->u.aft.security_id=0x01; + return 0; + } + + card->hw_iface.hw_lock(card->hw,&smp_flags); + wan_spin_lock_irq(&card->wandev.lock,&flags); + adptr_security=aft_read_cpld(card,0x09); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + adptr_security=(adptr_security>>2)&0x03; + card->u.aft.security_id=adptr_security; + + if (adptr_security == 0x00){ + DEBUG_EVENT("%s: AFT Security: UnChannelised\n", + card->devname); + }else if (adptr_security == 0x01){ + DEBUG_EVENT("%s: AFT Security: Channelised\n", + card->devname); + }else{ + DEBUG_EVENT("%s: AFT Security: Unknown\n", + card->devname); + return -EINVAL; + } + + card->u.aft.security_cnt=0; + + return 0; +} + + +static int aft_front_end_mismatch_check(sdla_t * card) +{ + u32 reg; + + if (card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG, ®); + + if (IS_T1_CARD(card)){ + if (wan_test_bit(AFT_CHIPCFG_TE1_CFG_BIT,®)){ + DEBUG_EVENT("%s: Global Cfg Error: Initial front end cfg: E1\n", + card->devname); + return -EINVAL; + } + }else{ + if (!wan_test_bit(AFT_CHIPCFG_TE1_CFG_BIT,®)){ + DEBUG_EVENT("%s: Global Cfg Error: Initial front end cfg: T1\n", + card->devname); + return -EINVAL; + } + } + } + + return 0; +} + +static int aft_realign_skb_pkt(private_area_t *chan, netskb_t *skb) +{ + unsigned char *data=wan_skb_data(skb); + int len = wan_skb_len(skb); + + if (len > chan->dma_mru){ + DEBUG_EVENT("%s: Critical error: Tx unalign pkt(%d) > MTU buf(%d)!\n", + chan->if_name,len,chan->dma_mru); + return -ENOMEM; + } + + if (!chan->tx_realign_buf){ + chan->tx_realign_buf=wan_malloc(chan->dma_mru); + if (!chan->tx_realign_buf){ + DEBUG_EVENT("%s: Error: Failed to allocate tx memory buf\n", + chan->if_name); + return -ENOMEM; + }else{ + DEBUG_EVENT("%s: AFT Realign buffer allocated Len=%d\n", + chan->if_name,chan->dma_mru); + + } + } + + memcpy(chan->tx_realign_buf,data,len); + + wan_skb_init(skb,0); + wan_skb_trim(skb,0); + + if (wan_skb_tailroom(skb) < len){ + DEBUG_EVENT("%s: Critical error: Tx unalign pkt tail room(%i) < unalign len(%i)!\n", + chan->if_name,wan_skb_tailroom(skb),len); + + return -ENOMEM; + } + + data=wan_skb_put(skb,len); + + if ((unsigned long)data & 0x03){ + /* At this point pkt should be realigned. If not + * there is something really wrong! */ + return -EINVAL; + } + + memcpy(data,chan->tx_realign_buf,len); + + chan->opstats.Data_frames_Tx_realign_count++; + + return 0; +} + +void aft_wdt_set(sdla_t *card, unsigned char val) +{ + u8 reg; + u32 wdt_ctrl_reg=AFT_WDT_1TO4_CTRL_REG+card->wandev.comm_port; + + if (card->wandev.comm_port > 3) { + wdt_ctrl_reg=AFT_WDT_4TO8_CTRL_REG+(card->wandev.comm_port%4); + } + + card->hw_iface.bus_read_1(card->hw,wdt_ctrl_reg, ®); + aft_wdt_ctrl_set(®,val); + card->hw_iface.bus_write_1(card->hw,wdt_ctrl_reg, reg); +} +void aft_wdt_reset(sdla_t *card) +{ + u8 reg; + u32 wdt_ctrl_reg=AFT_WDT_1TO4_CTRL_REG+card->wandev.comm_port; + + if (card->wandev.comm_port > 3) { + wdt_ctrl_reg=AFT_WDT_4TO8_CTRL_REG+(card->wandev.comm_port%4); + } + + card->hw_iface.bus_read_1(card->hw, wdt_ctrl_reg, ®); + aft_wdt_ctrl_reset(®); + card->hw_iface.bus_write_1(card->hw, wdt_ctrl_reg, reg); +} + +#if defined(__LINUX__) +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +static void aft_port_task (void * card_ptr) +# else +static void aft_port_task (struct work_struct *work) +# endif +#else +static void aft_port_task (void * card_ptr, int arg) +#endif +{ +#if defined(__LINUX__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) + sdla_t *card = (sdla_t *)container_of(work, sdla_t, u.aft.port_task); +#else + sdla_t *card = (sdla_t *)card_ptr; +#endif + wan_smp_flag_t smp_flags; + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + return; + } + + DEBUG_56K("%s: PORT TASK: 0x%X\n", card->devname,card->u.aft.port_task_cmd); + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_missed_errors++; +#endif + + + if (wan_test_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd)){ + + DEBUG_TEST("%s: PORT TASK: FE INTER\n", card->devname); + + card->hw_iface.hw_lock(card->hw,&smp_flags); + aft_fe_intr_ctrl(card, 0); + front_end_interrupt(card,0,1); + wan_clear_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd); + aft_fe_intr_ctrl(card, 1); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + } + + if (wan_test_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd)){ + DEBUG_TEST("%s: PORT TASK: FE POLL\n", card->devname); + card->hw_iface.hw_lock(card->hw,&smp_flags); + aft_fe_intr_ctrl(card, 0); + if (card->wandev.fe_iface.polling){ + wan_smp_flag_t smp_irq_flags; + int err = 0; + err = card->wandev.fe_iface.polling(&card->fe); + + wan_spin_lock_irq(&card->wandev.lock,&smp_irq_flags); + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_irq_flags); + } + wan_clear_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd); + aft_fe_intr_ctrl(card, 1); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + } + + if (wan_test_bit(AFT_FE_LED,&card->u.aft.port_task_cmd)){ + DEBUG_TEST("%s: PORT TASK: FE LED\n", card->devname); + card->hw_iface.hw_lock(card->hw,&smp_flags); + aft_fe_intr_ctrl(card, 0); + if (card->wandev.state == WAN_CONNECTED){ + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_OFF); + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_ON); + }else{ + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_ON); + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_OFF); + } + wan_clear_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); + aft_fe_intr_ctrl(card, 1); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + } + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (wan_test_bit(AFT_FE_TDM_RBS,&card->u.aft.port_task_cmd)){ + int err; + DEBUG_TEST("%s: PORT TASK: FE RBS\n", card->devname); + card->hw_iface.hw_lock(card->hw,&smp_flags); + + WAN_TDMV_CALL(rbsbits_poll, (&card->wan_tdmv, card), err); + + wan_clear_bit(AFT_FE_TDM_RBS,&card->u.aft.port_task_cmd); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + } +#endif + +#if defined(CONFIG_WANPIPE_HWEC) + if (wan_test_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd)){ + + DEBUG_TEST("%s: PORT TASK: FE EC INTR\n", card->devname); + + if (card->wandev.ec_dev){ + card->hw_iface.hw_ec_lock(card->hw,&smp_flags); + wanpipe_ec_poll(card->wandev.ec_dev, card); + wan_clear_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd); + card->hw_iface.hw_ec_unlock(card->hw,&smp_flags); + } + } +#endif + + + if (wan_test_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd)){ + wan_clear_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd); + if (card->fe.fe_status == FE_CONNECTED) { + DEBUG_EVENT("%s: TDM IRQ Restart\n", + card->devname); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + card->fe.fe_status = FE_DISCONNECTED; + handle_front_end_state(card); + card->fe.fe_status = FE_CONNECTED; + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + } + } +} + +void __aft_fe_intr_ctrl(sdla_t *card, int status) +{ + u32 reg; + + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG,®); + if (status){ + wan_set_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®); + }else{ + wan_clear_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®); + } + card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + +} + +void aft_fe_intr_ctrl(sdla_t *card, int status) +{ + wan_smp_flag_t smp_flags; + + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + __aft_fe_intr_ctrl(card,status); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + +} + +static void aft_data_mux_cfg(sdla_t *card) +{ + if (!card->u.aft.cfg.data_mux_map){ + card->u.aft.cfg.data_mux_map=AFT_DEFAULT_DATA_MUX_MAP; + } + + card->hw_iface.bus_write_4(card->hw, AFT_DATA_MUX_REG, + card->u.aft.cfg.data_mux_map); + + DEBUG_EVENT("%s: AFT Data Mux Bit Map: 0x%08X\n", + card->devname,card->u.aft.cfg.data_mux_map); +} + +static void aft_data_mux_get_cfg(sdla_t *card) +{ + card->hw_iface.bus_read_4(card->hw, AFT_DATA_MUX_REG, + &card->u.aft.cfg.data_mux_map); + +} + + +static int aft_ss7_tx_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb) +{ + int ss7_len=0,len=0; + unsigned int ss7_ctrl=0; + unsigned char *buf; + api_tx_hdr_t *tx_hdr = &chan->tx_api_hdr; + + memcpy(&chan->tx_api_hdr,wan_skb_data(skb),sizeof(api_tx_hdr_t)); + wan_skb_pull(skb,sizeof(api_tx_hdr_t)); + + if (!chan->tx_ss7_realign_buf){ + chan->tx_ss7_realign_buf=wan_malloc(chan->dma_mru); + if (!chan->tx_ss7_realign_buf){ + DEBUG_EVENT("%s: Error: Failed to allocate ss7 tx memory buf\n", + chan->if_name); + return -ENOMEM; + }else{ + DEBUG_TEST("%s: AFT SS7 Realign buffer allocated Len=%d\n", + chan->if_name,chan->dma_mru); + } + } + + memset(chan->tx_ss7_realign_buf,0,chan->dma_mru); + memcpy(chan->tx_ss7_realign_buf,wan_skb_data(skb),wan_skb_len(skb)); + len=wan_skb_len(skb); + + /* Align the end of the frame to 32 byte boundary */ + ss7_ctrl=(len%4)&AFT_SS7_CTRL_LEN_MASK; + if (ss7_ctrl != 0){ + len-=len%4; + len+=4; + } + + if (tx_hdr->u.ss7.type == WANOPT_SS7_FISU){ + if (chan->cfg.ss7_mode == WANOPT_SS7_MODE_4096){ + ss7_len=WANOPT_SS7_FISU_4096_SZ; + }else{ + ss7_len=WANOPT_SS7_FISU_128_SZ; + } + wan_clear_bit(AFT_SS7_CTRL_TYPE_BIT,&ss7_ctrl); + }else{ + ss7_len=chan->cfg.ss7_lssu_size; + wan_set_bit(AFT_SS7_CTRL_TYPE_BIT,&ss7_ctrl); + } + + if (tx_hdr->u.ss7.force_tx){ + wan_set_bit(AFT_SS7_CTRL_FORCE_BIT,&ss7_ctrl); + }else{ + wan_clear_bit(AFT_SS7_CTRL_FORCE_BIT,&ss7_ctrl); + } + + DEBUG_TEST("%s: SS7 DATA = 0x%X 0x%X 0x%X\n", + chan->if_name, + tx_hdr->u.ss7.data[0], + tx_hdr->u.ss7.data[1], + tx_hdr->u.ss7.data[2]); + + memcpy(&chan->tx_ss7_realign_buf[len],tx_hdr->u.ss7.data,ss7_len); + + len+=ss7_len; + + wan_skb_init(skb,0); + wan_skb_trim(skb,0); + + if (wan_skb_tailroom(skb) < len){ + DEBUG_EVENT("%s: Critical error: SS7 Tx unalign pkt tail room(%i) < len(%i)!\n", + chan->if_name,wan_skb_tailroom(skb),len); + + return -ENOMEM; + } + + buf=wan_skb_put(skb,len); + memcpy(buf,chan->tx_ss7_realign_buf,len); + + wan_skb_set_csum(skb, ss7_ctrl); + +#if 0 + debug_print_skb_pkt(chan->if_name, wan_skb_data(skb), wan_skb_len(skb), 0); +#endif + return 0; +} + + + + +#if 0 +static void aft_chain_history(private_area_t *chan,u8 end, u8 cur, u8 begin, u8 loc) +{ + dma_history_t *dma_hist = &chan->dma_history[chan->dma_index]; + + dma_hist->loc=loc; + dma_hist->end=end; + dma_hist->cur=cur; + dma_hist->begin=begin; + dma_hist->status=0; + + if (end > begin){ + if (cur > end || + cur < begin){ + DEBUG_TEST("%s: Rx: Critical: RxPendChain=%d HWDMA=%d RxEndChain=%d\n", + chan->if_name,begin,cur,end); + dma_hist->status=1; + } + }else if (end < begin){ + if (cur < begin && + cur > end){ + DEBUG_TEST("%s: Rx: Critical: RxEndChain=%d HWDMA=%d RxPendingChain=%d\n", + chan->if_name,begin,cur,end); + dma_hist->status=1; + + } + } + + if (++chan->dma_index >= MAX_DMA_HIST_SIZE){ + chan->dma_index=0; + } +} +#endif + +#if 0 +static void aft_display_chain_history(private_area_t *chan) +{ + int start=chan->dma_index; + int i; + dma_history_t *dma_hist = &chan->dma_history[start]; + + for (i=0;iloc == 0){ + continue; + } + + DEBUG_EVENT("%s: Loc=%02i End=%02d Cur=%02d Beg=%02d St=%s\n", + chan->if_name, + dma_hist->loc, + dma_hist->end, + dma_hist->cur, + dma_hist->begin, + dma_hist->status?"Error":"Ok"); + + start++; + if (start >= MAX_DMA_HIST_SIZE){ + start=0; + } + dma_hist = &chan->dma_history[start]; + } +} +#endif + +/* + * ****************************************************************** + * Proc FS function + */ +static int wan_aft_get_info(void* pcard, struct seq_file *m, int *stop_cnt) +{ + sdla_t *card = (sdla_t*)pcard; + + if (card->wandev.fe_iface.update_alarm_info){ + m->count = + WAN_FECALL( + &card->wandev, + update_alarm_info, + (&card->fe, m, stop_cnt)); + } + if (card->wandev.fe_iface.update_pmon_info){ + m->count = + WAN_FECALL( + &card->wandev, + update_pmon_info, + (&card->fe, m, stop_cnt)); + } + + return m->count; +} + +static int aft_tdmv_init(sdla_t *card, wandev_conf_t *conf) +{ + + int err; + int valid_firmware_ver=AFT_TDMV_FRM_VER; + + err=0; + DEBUG_EVENT("%s: TDMV Span = %d : %s\n", + card->devname, + card->tdmv_conf.span_no, + card->tdmv_conf.span_no?"Enabled":"Disabled"); + + if (card->tdmv_conf.span_no) { + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG) { + valid_firmware_ver=AFT_MIN_ANALOG_FRMW_VER; + } + + if (card->u.aft.firm_ver < valid_firmware_ver){ + DEBUG_EVENT("%s: Error: Obselete AFT Firmware version: %X\n", + card->devname,card->u.aft.firm_ver); + DEBUG_EVENT("%s: Error: AFT TDMV Support depends on Firmware Ver >= %X\n", + card->devname,valid_firmware_ver); + return -EINVAL; + } + } + + + + return 0; + +} + + +/************************************************************** + * TDMV VOICE Functions + **************************************************************/ +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) +static int aft_tdmv_free(sdla_t *card) +{ + if (card->tdmv_conf.span_no && card->wan_tdmv.sc){ + int err; + WAN_TDMV_CALL(remove, (card), err); + } + return 0; +} +#endif + + +static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) +{ + + if (!chan->channelized_cfg){ + return 0; + } + + if (!card->tdmv_conf.span_no){ + DEBUG_EVENT("%s: Error: TDMV Span No is not set!\n", + card->devname); + return -EINVAL; + } + + if (chan->cfg.tdmv_master_if){ + DEBUG_EVENT("%s: Configuring TDMV Master dev %s\n", + card->devname,chan->if_name); + + /* Initialize a TDM bottom half handler + * Optionally used */ + WAN_TASKLET_INIT((&chan->common.bh_task),0,wp_tdm_bh,chan); + } + + if (conf->hdlc_streaming == 0){ + + int err; + + err=0; + + aft_hwdev[card->wandev.card_type].aft_fifo_adjust(card,AFT_TDMV_FIFO_LEVEL); + + if (chan->common.usedby == TDM_VOICE) { +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + WAN_TDMV_CALL(check_mtu, (card, conf->active_ch, &chan->mtu), err); + if (err){ + DEBUG_EVENT("Error: TMDV mtu check failed!"); + return -EINVAL; + } +#endif + } + + if (chan->common.usedby == TDM_VOICE_API) { + switch (chan->mtu) { + case 8: + case 16: + break; + case 40: + case 80: + if (!wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + /* If Global TDM Feature is not enable + then 40 and 80 bytes TDM are not available */ + chan->mtu=16; + } + break; + default: + chan->mtu=16; + break; + } + } + + chan->mru = chan->mtu; + + card->u.aft.tdmv_mtu += chan->mtu; + + if (chan->tdmv_zaptel_cfg){ + chan->cfg.data_mux=1; + } + + conf->hdlc_streaming=0; + chan->tx_realign_buf = NULL; +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + card->wan_tdmv.brt_enable=0; +#endif + + }else{ + chan->cfg.data_mux=0; + } + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (chan->tdmv_zaptel_cfg){ + int channel; + + /* The TDMV drivers always starts from number + * ZERO. Wanpipe driver doesn't allow timeslot + * ZERO. Thus, the active_ch map must me adjusted + * before calling tdmv_reg */ + if (IS_E1_CARD(card)){ + conf->active_ch=conf->active_ch>>1; + } + + WAN_TDMV_CALL(reg, + (card, + &conf->tdmv, + conf->active_ch, + conf->hwec.enable, + chan->common.dev), channel); + if (channel < 0){ + DEBUG_EVENT("%s: Error: Failed to register TDMV channel!\n", + chan->if_name); + + return -EINVAL; + } + chan->tdmv_chan=channel; + + + if (card->u.aft.tdmv_dchan_cfg_on_master && chan->cfg.tdmv_master_if){ + u32 orig_ch=conf->active_ch; + + conf->active_ch=card->u.aft.tdmv_dchan_cfg_on_master; + + WAN_TDMV_CALL(reg, + (card, + &conf->tdmv, + conf->active_ch, + conf->hwec.enable, + chan->common.dev), channel); + if (channel < 0){ + DEBUG_EVENT("%s: Error: Failed to register TDMV channel!\n", + chan->if_name); + + return -EINVAL; + } + + card->u.aft.tdmv_chan=channel; + card->u.aft.tdmv_dchan_active_ch=conf->active_ch; + conf->active_ch=orig_ch; + } + } +#endif + + return 0; + +} + + +static int aft_tdmv_if_free(sdla_t *card, private_area_t *chan) +{ +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (chan->tdmv_zaptel_cfg){ + int err; + WAN_TDMV_CALL(unreg, (card, chan->time_slot_map), err); + if (err){ + return err; + } + + if (card->u.aft.tdmv_dchan_cfg_on_master && chan->cfg.tdmv_master_if){ + DEBUG_EVENT("%s: Card Unregistering DCHAN\n", + card->devname); + WAN_TDMV_CALL(unreg, (card, card->u.aft.tdmv_dchan_active_ch), err); + card->u.aft.tdmv_dchan_cfg_on_master=0; + } + } +#endif + return 0; +} + +#if 0 +/* NCDEBUG */ +static int gtmp_cnt=0; +static void aft_set_channel(sdla_t *card, int ch) +{ + aft_dma_chain_t *tx_dma_chain; + u8 *buf; + private_area_t *chan=(private_area_t*)card->u.aft.dev_to_ch_map[ch]; + + if (!chan) return; + + tx_dma_chain = &chan->tx_dma_chain_table[0]; + if (!tx_dma_chain){ + return; + } + buf = (u8*)wan_skb_data(tx_dma_chain->skb); + buf[0]=gtmp_cnt++; + buf[1]=gtmp_cnt++; + buf[2]=gtmp_cnt++; + buf[3]=gtmp_cnt++; + buf[4]=gtmp_cnt++; + buf[5]=gtmp_cnt++; + buf[6]=gtmp_cnt++; + buf[7]=gtmp_cnt++; + + card->wandev.stats.tx_packets++; +} +#endif + + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) +static int aft_voice_span_rx_tx(sdla_t *card, int rotate) +{ + int err; + err=0; + + if (card->wan_tdmv.sc){ + + if (rotate) { + WAN_TDMV_CALL(buf_rotate, (card,AFT_TDMV_CIRC_BUF,AFT_TDMV_BUF_MASK), err); + } + + if (!card->wandev.ec_enable || card->wandev.ec_enable_map == 0){ + WAN_TDMV_CALL(ec_span, (card), err); + } + + WAN_TDMV_CALL(rx_tx_span, (card), err); + + WAN_TDMV_CALL(is_rbsbits, (&card->wan_tdmv), err); + if (err == 1){ + wan_set_bit(AFT_FE_TDM_RBS,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } + +#if !defined(AFT_IRQ_DEBUG) + card->wandev.stats.rx_packets++; + card->wandev.stats.tx_packets++; +#endif + + } + return 0; +} +#endif + +static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) +{ + int err; + u32 rx_offset=0; + u32 tx_offset=0; + + aft_dma_chain_t *tx_dma_chain; + aft_dma_chain_t *rx_dma_chain; + + tx_dma_chain = &chan->tx_dma_chain_table[0]; + rx_dma_chain = &chan->rx_dma_chain_table[0]; + + + if (wan_test_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status)) { + rx_offset= AFT_TDMV_CIRC_BUF * card->u.aft.tdm_rx_dma_toggle; + tx_offset= AFT_TDMV_CIRC_BUF * card->u.aft.tdm_tx_dma_toggle; + } + + err=0; + + if (!tx_dma_chain || !rx_dma_chain){ + DEBUG_EVENT("%s: %s:%d ASSERT ERROR TxDma=%p RxDma=%p\n", + card->devname,__FUNCTION__,__LINE__, + tx_dma_chain,rx_dma_chain); + return -EINVAL; + } + + if (!rx_dma_chain->skb || !tx_dma_chain->skb){ + DEBUG_TEST("%s: %s:%d ASSERT ERROR TxSkb=%p RxSkb=%p\n", + card->devname,__FUNCTION__,__LINE__, + rx_dma_chain->skb,tx_dma_chain->skb); + return -EINVAL; + } + +#if 0 + /*Measure the round trip delay*/ + if (!chan->tdmv_rx_delay_cfg){ + int i; + unsigned char *buf=rx_dma_chain->dma_virt+offset; + for (i=0;i<8;i++){ + if (buf[i]==0x55){ + chan->tdmv_rx_delay_cfg=1; + DEBUG_EVENT("%s: Chan=%ld Delay=%d\n", + chan->if_name,chan->logic_ch_num, + chan->tdmv_rx_delay); + break; + } + chan->tdmv_rx_delay++; + } + } +#endif + + + if (chan->tdmv_zaptel_cfg){ +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (card->wan_tdmv.sc){ + +#if 0 +defined(AFT_TDMV_BH_ENABLE) + aft_dma_chain_t *tx_bh_dma_chain = &chan->tx_dma_chain_table[1]; + aft_dma_chain_t *rx_bh_dma_chain = &chan->rx_dma_chain_table[1]; + + if (!rx_bh_dma_chain->skb){ + rx_bh_dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!rx_bh_dma_chain->skb){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical TDM BH no free skb\n", + chan->if_name); + goto aft_tdm_bh_skip; + } + } + wan_skb_init(rx_bh_dma_chain->skb,16); + wan_skb_trim(rx_bh_dma_chain->skb,0); + } + + if (!tx_bh_dma_chain->skb){ + tx_bh_dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!tx_bh_dma_chain->skb){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical TDM BH no free skb\n", + chan->if_name); + goto aft_tdm_bh_skip; + } + } + wan_skb_init(tx_bh_dma_chain->skb,16); + wan_skb_trim(tx_bh_dma_chain->skb,0); + } + + memcpy(wan_skb_data(rx_bh_dma_chain->skb), + wan_skb_data(rx_dma_chain->skb),8); + + memcpy(wan_skb_data(tx_dma_chain->skb), + wan_skb_data(tx_bh_dma_chain->skb),8); + + rx_dma_chain=rx_bh_dma_chain; + tx_dma_chain=tx_bh_dma_chain; +aft_tdm_bh_skip: +#endif + + DEBUG_TEST ("%s: Calling Rx Chan=%i TdmvChan=%i\n", + card->devname,chan->logic_ch_num, + chan->tdmv_chan); +#if 1 + +#if 0 +#warning "RTP TAP ENABLED Not Finished" + if (card->u.aft.rtp_len) { + aft_rtp_tap(card,chan, + rx_dma_chain->dma_virt+rx_offset, + tx_dma_chain->dma_virt+tx_offset, + chan->mtu); + } +#endif + WAN_TDMV_CALL(rx_chan, + (&card->wan_tdmv,chan->tdmv_chan, + rx_dma_chain->dma_virt+rx_offset, + tx_dma_chain->dma_virt+tx_offset), + err); +#else +#warning "NCDEBUG rx_chan disabled irq" +#endif + +#if 0 + if (((u8*)(rx_dma_chain->dma_virt+offset))[0] != 0xFF && + ((u8*)(rx_dma_chain->dma_virt+offset))[0] != 0x7F && + tx_debug_cnt < 100){ + DEBUG_EVENT("%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", + card->devname, + ((u8*)(rx_dma_chain->dma_virt+offset))[0], + ((u8*)(rx_dma_chain->dma_virt+offset))[1], + ((u8*)(rx_dma_chain->dma_virt+offset))[2], + ((u8*)(rx_dma_chain->dma_virt+offset))[3], + ((u8*)(rx_dma_chain->dma_virt+offset))[4], + ((u8*)(rx_dma_chain->dma_virt+offset))[5], + ((u8*)(rx_dma_chain->dma_virt+offset))[6], + ((u8*)(rx_dma_chain->dma_virt+offset))[7]); + tx_debug_cnt++; + } +#endif + }else{ + return 1; + } +#endif + }else{ + +#ifdef AFT_TDM_API_SUPPORT + + if (card->wandev.fe_iface.watchdog){ + err = card->wandev.fe_iface.watchdog(&card->fe); + } + + wanpipe_tdm_api_rx_tx(&chan->wp_tdm_api_dev, + rx_dma_chain->dma_virt+rx_offset, + tx_dma_chain->dma_virt+tx_offset, + chan->mtu); +#endif + } + + if (chan->cfg.tdmv_master_if){ + u32 reg; + int err; + err=0; +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (chan->tdmv_zaptel_cfg){ + DEBUG_TEST ("%s: Calling Master Rx Tx Chan=%i\n", + card->devname,chan->logic_ch_num); +#if 0 +defined(AFT_TDMV_BH_ENABLE) +#warning "AFT A104: TDM Driver compiled in BH mode!" + + if (WAN_TASKLET_RUNNING((&chan->common.bh_task))){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical Error: TDMV BH Overrun!\n", + card->devname); + } + } + + WAN_WP_TASKLET_SCHEDULE_PER_CPU((&chan->common.bh_task), + card->tdmv_conf.span_no); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,®); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + +#else +#if 1 + WAN_TDMV_CALL(rx_tx_span, (card), err); +#else +#warning "NCDEBUG: rx_tx_span disabled irq" +#endif + + + if (!wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,®); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + } + + if (card->wan_tdmv.sc){ + WAN_TDMV_CALL(is_rbsbits, (&card->wan_tdmv), err); + if (err == 1){ + wan_set_bit(AFT_FE_TDM_RBS,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } + } +#endif + }else{ +#else + if (!chan->tdmv_zaptel_cfg){ + +#endif + if (!wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,®); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + } + } + + DEBUG_TEST("%s: Master device tx rx %i!\n", + card->devname,chan->logic_ch_num); + } + + chan->opstats.Data_frames_Rx_count++; + chan->opstats.Data_bytes_Rx_count+=chan->mru; + chan->opstats.Data_frames_Tx_count++; + chan->opstats.Data_bytes_Tx_count+=chan->mtu; + chan->if_stats.rx_packets++; + chan->if_stats.rx_bytes += chan->mru; + chan->if_stats.tx_packets++; + chan->if_stats.tx_bytes += chan->mtu; + + return 0; +} + +static int aft_fifo_intr_ctrl(sdla_t *card, int ctrl) +{ + u32 reg; + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG), + ®); + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG), + ®); + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + + if (ctrl){ + wan_set_bit(AFT_LCFG_FIFO_INTR_BIT,®); + }else{ + wan_clear_bit(AFT_LCFG_FIFO_INTR_BIT,®); + } + + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + + card->u.aft.lcfg_reg=reg; + + + if (!ctrl){ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG), + ®); + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG), + ®); + } + + return 0; +} + +static int aft_tdm_intr_ctrl(sdla_t *card, int ctrl) +{ + u32 reg; + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + + if (ctrl){ + wan_set_bit(AFT_LCFG_TDMV_INTR_BIT,®); + + }else{ + wan_clear_bit(AFT_LCFG_TDMV_INTR_BIT,®); + } + + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + + card->u.aft.lcfg_reg=reg; + + return 0; +} + +#if defined(AFT_API_SUPPORT) +static int wan_aft_api_ioctl(sdla_t *card, private_area_t *chan, char *user_data) +{ + api_tx_hdr_t tx_hdr; + wan_event_ctrl_t event_ctrl; + int err = -EINVAL; + + if (WAN_COPY_FROM_USER(&tx_hdr, user_data, sizeof(api_tx_hdr_t))){ + DEBUG_EVENT("%s: Failed to copy data from user space!\n", + card->devname); + return -EFAULT; + } + memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); + switch(tx_hdr.wp_api_tx_hdr_event_type){ + case WP_API_EVENT_DTMF: + DEBUG_TEST("%s: %s HW DTMF events!\n", + card->devname, + (tx_hdr.wp_api_tx_hdr_event_mode==WP_API_EVENT_ENABLE)? + "Enable": "Disable"); + event_ctrl.type = WAN_EVENT_EC_DTMF; + event_ctrl.ts_map = tx_hdr.wp_api_tx_hdr_event_channel; + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + + case WP_API_EVENT_RM_DTMF: + DEBUG_TEST("%s: %s RM DTMF events!\n", + card->devname, + (tx_hdr.wp_api_tx_hdr_event_mode==WP_API_EVENT_ENABLE)? + "Enable": "Disable"); + event_ctrl.type = WAN_EVENT_RM_DTMF; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + + case WP_API_EVENT_RXHOOK: + DEBUG_TEST("%s: %s OFFHOOK/ONHOOK events!\n", + card->devname, + (tx_hdr.wp_api_tx_hdr_event_mode==WP_API_EVENT_ENABLE)? + "Enable": "Disable"); + event_ctrl.type = WAN_EVENT_RM_LC; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_RING: + DEBUG_TEST("%s: %s RING events!\n", + card->devname, + (tx_hdr.wp_api_tx_hdr_event_mode==WP_API_EVENT_ENABLE)? + "Enable": "Disable"); + event_ctrl.type = WAN_EVENT_RM_RING; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_TONE: + DEBUG_TEST("%s: %s TONE events!\n", + card->devname, + (tx_hdr.wp_api_tx_hdr_event_mode==WP_API_EVENT_ENABLE)? + "Enable": "Disable"); + event_ctrl.type = WAN_EVENT_RM_TONE; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + switch(tx_hdr.wp_api_tx_hdr_event_tone){ + case WP_API_EVENT_TONE_DIAL: + event_ctrl.tone = WAN_EVENT_TONE_DIAL; + break; + case WP_API_EVENT_TONE_BUSY: + event_ctrl.tone = WAN_EVENT_TONE_BUSY; + break; + case WP_API_EVENT_TONE_RING: + event_ctrl.tone = WAN_EVENT_TONE_RING; + break; + case WP_API_EVENT_TONE_CONGESTION: + event_ctrl.tone = WAN_EVENT_TONE_CONGESTION; + break; + default: + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + DEBUG_EVENT("%s: Unsupported tone type %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_tone); + return -EINVAL; + } + break; + } + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + + case WP_API_EVENT_TXSIG_KEWL: + DEBUG_EVENT("%s: TXSIG KEWL for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_TXSIG_KEWL; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_TXSIG_START: + DEBUG_EVENT("%s: TXSIG START for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_TXSIG_START; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_TXSIG_OFFHOOK: + DEBUG_EVENT("%s: RM TXSIG OFFHOOK for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_TXSIG_OFFHOOK; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_TXSIG_ONHOOK: + DEBUG_EVENT("%s: RM TXSIG ONHOOK for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_TXSIG_ONHOOK; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_ONHOOKTRANSFER: + DEBUG_EVENT("%s: RM ONHOOKTRANSFER for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_ONHOOKTRANSFER; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + event_ctrl.ohttimer = tx_hdr.wp_api_tx_hdr_event_ohttimer; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_SETPOLARITY: + DEBUG_EVENT("%s: RM SETPOLARITY for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_SETPOLARITY; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + event_ctrl.polarity = tx_hdr.wp_api_tx_hdr_event_polarity; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_RING_DETECT: + DEBUG_EVENT("%s: %s: RM RING DETECT events for module %d!\n", + card->devname, + WP_API_EVENT_MODE_DECODE(tx_hdr.wp_api_tx_hdr_event_mode), + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_RING_DETECT; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + + default: + DEBUG_EVENT("%s: Unknown event type %02X!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_type); + err = -EINVAL; + break; + } + return err; +} +#endif + +#if defined(AFT_API_SUPPORT) +static void wan_aft_api_dtmf (void* card_id, wan_event_t *event) +{ + sdla_t *card = (sdla_t*)card_id; + private_area_t *chan = NULL; + netskb_t *new_skb = NULL; + api_rx_hdr_t *rx_hdr; + int i; + + if (event->type == WAN_EVENT_EC_DTMF){ + DEBUG_TEST("%s: Received DTMF Event at AFT API (%d:%c:%s:%s)!\n", + card->devname, + event->channel, + event->digit, + (event->dtmf_port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT", + (event->dtmf_type == WAN_EC_TONE_PRESENT)?"PRESENT":"STOP"); + }else if (event->type == WAN_EVENT_RM_DTMF){ + DEBUG_TEST("%s: Received DTMF Event at AFT API (%d:%c)!\n", + card->devname, + event->channel, + event->digit); + } + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&card->u.aft.logic_ch_map)){ + unsigned long ts_map; + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + ts_map = chan->time_slot_map; + if (IS_T1_CARD(card) || IS_FXOFXS_CARD(card)){ + /* Convert active_ch bit map to user */ + ts_map = ts_map << 1; + } + if (wan_test_bit(event->channel,&ts_map)){ + break; + } + chan = NULL; + } + } + if (chan == NULL){ + DEBUG_EVENT("%s: Failed to find channel device (channel=%d)!\n", + card->devname, event->channel); + return; + } +#if defined(__LINUX__) + new_skb=wan_skb_alloc(sizeof(api_rx_element_t)); + if (new_skb == NULL) return; + + rx_hdr=(api_rx_hdr_t*)wan_skb_put(new_skb,sizeof(api_rx_element_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + + rx_hdr->error_flag = 0; + rx_hdr->event_type = WP_API_EVENT_DTMF; + rx_hdr->wp_api_rx_hdr_event_channel = event->channel; + rx_hdr->wp_api_rx_hdr_event_dtmf_digit = event->digit; + rx_hdr->wp_api_rx_hdr_event_dtmf_type = event->dtmf_type; + rx_hdr->wp_api_rx_hdr_event_dtmf_port = event->dtmf_port; + + new_skb->protocol = htons(PVC_PROT); + wan_skb_reset_mac_header(new_skb); + new_skb->dev = chan->common.dev; + new_skb->pkt_type = WAN_PACKET_DATA; + + //if (wan_api_rx_dtmf(chan,new_skb) != 0){ + if (wan_api_rx(chan,new_skb) != 0){ + DEBUG_EVENT("%s: Failed to send up DTMF event!\n", + card->devname); + wan_skb_free(new_skb); + } +#else + DEBUG_EVENT("%s:%s: DTMF Event report is not supported!\n", + card->devname, chan->if_name); + new_skb = NULL; + rx_hdr = NULL; +#endif + return; +} +#endif + +#if defined(AFT_API_SUPPORT) +static void wan_aft_api_hook (void* card_id, wan_event_t *event) +{ + sdla_t *card = (sdla_t*)card_id; + private_area_t *chan = NULL; + netskb_t *new_skb = NULL; + api_rx_hdr_t *rx_hdr; + int i; + + if (event->type != WAN_EVENT_RM_LC){ + DEBUG_EVENT("ERROR: %s: Invalid Event type (%04X)!\n", + card->devname, event->type); + return; + } + DEBUG_EVENT("%s: Received %s (%d) Event at AFT API (%d)!\n", + card->devname, + WAN_EVENT_RXHOOK_DECODE(event->rxhook), event->rxhook, + event->channel); + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&card->u.aft.logic_ch_map)){ + unsigned long ts_map; + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + ts_map = chan->time_slot_map; + if (IS_T1_CARD(card) || IS_FXOFXS_CARD(card)){ + /* Convert active_ch bit map to user */ + ts_map = ts_map << 1; + } + if (wan_test_bit(event->channel,&ts_map)){ + break; + } + chan = NULL; + } + } + if (chan == NULL){ + DEBUG_EVENT("%s: Failed to find channel device (channel=%d)!\n", + card->devname, event->channel); + return; + } +#if defined(__LINUX__) + new_skb=wan_skb_alloc(sizeof(api_rx_element_t)); + if (new_skb == NULL) return; + + rx_hdr=(api_rx_hdr_t*)wan_skb_put(new_skb,sizeof(api_rx_element_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + + rx_hdr->error_flag = 0; + rx_hdr->event_type = WP_API_EVENT_RXHOOK; + rx_hdr->wp_api_rx_hdr_event_channel = event->channel; + if (event->rxhook == WAN_EVENT_RXHOOK_OFF){ + rx_hdr->wp_api_rx_hdr_event_rxhook_state = WP_API_EVENT_RXHOOK_OFF; + }else if (event->rxhook == WAN_EVENT_RXHOOK_ON){ + rx_hdr->wp_api_rx_hdr_event_rxhook_state = WP_API_EVENT_RXHOOK_ON; + } + + new_skb->protocol = htons(PVC_PROT); + wan_skb_reset_mac_header(new_skb); + new_skb->dev = chan->common.dev; + new_skb->pkt_type = WAN_PACKET_DATA; + + if (wan_api_rx(chan,new_skb) != 0){ + DEBUG_EVENT("%s: Failed to send up HOOK event!\n", + card->devname); + wan_skb_free(new_skb); + } +#else + DEBUG_EVENT("%s:%s: RXHOOK Event report is not supported!\n", + card->devname, chan->if_name); + new_skb = NULL; + rx_hdr = NULL; +#endif + return; +} +#endif + +#if defined(AFT_API_SUPPORT) +static void wan_aft_api_ringtrip (void* card_id, wan_event_t *event) +{ + sdla_t *card = (sdla_t*)card_id; + + DEBUG_EVENT("%s: Unsupported event!\n", card->devname); + return; +} +#endif + +#if defined(AFT_API_SUPPORT) +static void wan_aft_api_ringdetect (void* card_id, wan_event_t *event) +{ + sdla_t *card = (sdla_t*)card_id; + private_area_t *chan = NULL; + netskb_t *new_skb = NULL; + api_rx_hdr_t *rx_hdr; + int i; + + if (event->type != WAN_EVENT_RM_RING_DETECT){ + DEBUG_EVENT("ERROR: %s: Invalid Event type (%04X)!\n", + card->devname, event->type); + return; + } + DEBUG_EVENT("%s: Received Ring Detect %s (%d) Event at AFT API (%d)!\n", + card->devname, + WAN_EVENT_RING_DECODE(event->ring_mode), event->ring_mode, + event->channel); + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&card->u.aft.logic_ch_map)){ + unsigned long ts_map; + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + ts_map = chan->time_slot_map; + if (IS_T1_CARD(card) || IS_FXOFXS_CARD(card)){ + /* Convert active_ch bit map to user */ + ts_map = ts_map << 1; + } + if (wan_test_bit(event->channel,&ts_map)){ + break; + } + chan = NULL; + } + } + if (chan == NULL){ + DEBUG_EVENT("%s: Failed to find channel device (channel=%d)!\n", + card->devname, event->channel); + return; + } +#if defined(__LINUX__) + new_skb=wan_skb_alloc(sizeof(api_rx_element_t)); + if (new_skb == NULL) return; + + rx_hdr=(api_rx_hdr_t*)wan_skb_put(new_skb,sizeof(api_rx_element_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + + rx_hdr->error_flag = 0; + rx_hdr->event_type = WP_API_EVENT_RING_DETECT; + rx_hdr->wp_api_rx_hdr_event_channel = event->channel; + if (event->ring_mode == WAN_EVENT_RING_PRESENT){ + rx_hdr->wp_api_rx_hdr_event_ringdetect_state = WAN_EVENT_RING_PRESENT; + }else if (event->ring_mode == WAN_EVENT_RING_STOP){ + rx_hdr->wp_api_rx_hdr_event_ringdetect_state = WAN_EVENT_RING_STOP; + }else{ + DEBUG_EVENT("%s: Invalid Rind Detect mode (%d)!\n", + card->devname, event->ring_mode); + wan_skb_free(new_skb); + return ; + } + + new_skb->protocol = htons(PVC_PROT); + wan_skb_reset_mac_header(new_skb); + new_skb->dev = chan->common.dev; + new_skb->pkt_type = WAN_PACKET_DATA; + + if (wan_api_rx(chan,new_skb) != 0){ + DEBUG_EVENT("%s: Failed to send up HOOK event!\n", + card->devname); + wan_skb_free(new_skb); + } +#else + DEBUG_EVENT("%s:%s: RXHOOK Event report is not supported!\n", + card->devname, chan->if_name); + new_skb = NULL; + rx_hdr = NULL; +#endif + return; +} +#endif + +#if 0 +static void wp_tdmv_api_chan_rx_tx(sdla_t *card, + private_area_t *chan, + unsigned char *rxdata, unsigned char *txdata) +{ +#if defined(__LINUX__) + unsigned char *buf; + + if (!card->u.aft.tdmv_api_rx){ + card->u.aft.tdmv_api_rx=wan_skb_alloc(card->u.aft.tdmv_mtu); + if (!card->u.aft.tdmv_api_rx){ + ++chan->if_stats.rx_errors; + goto wp_tdmv_api_rx_tx_chan_skip_rx; + } + } + + if (wan_skb_len(card->u.aft.tdmv_api_rx) > (card->u.aft.tdmv_mtu-chan->mru)){ + /* CRITICAL ERROR: We cannot fit the all timeslots into this + * packet */ + ++chan->if_stats.rx_errors; + goto wp_tdmv_api_rx_tx_chan_skip_rx; + } + + buf=wan_skb_put(card->u.aft.tdmv_api_rx, chan->mru); + memcpy(buf,rxdata,chan->mru); + ++chan->if_stats.rx_dropped; + +wp_tdmv_api_rx_tx_chan_skip_rx: + + if (!card->u.aft.tdmv_api_tx){ + card->u.aft.tdmv_api_tx=wan_skb_dequeue(&card->u.aft.tdmv_api_tx_list); + if (!card->u.aft.tdmv_api_tx){ + /* No tx packet, send idle frames */ + ++chan->if_stats.tx_carrier_errors; + memset(txdata,chan->idle_flag,chan->mtu); + return; + } + } + + if (wan_skb_len(card->u.aft.tdmv_api_tx) < chan->mtu){ + /* CRITICAL ERROR: + * The tx api packet must have info for all + * timeslots */ + memset(txdata,chan->idle_flag,chan->mtu); + ++chan->if_stats.tx_errors; + return; + } + + buf=wan_skb_data(card->u.aft.tdmv_api_tx); + memcpy(txdata,buf,chan->mtu); + wan_skb_pull(card->u.aft.tdmv_api_tx,chan->mtu); + ++chan->if_stats.tx_dropped; + +#endif + return; +} + +/*================================================ + * wp_tdmv_api_rx_tx + * + * + */ + +static void wp_tdmv_api_rx_tx (sdla_t *card, private_area_t *chan) +{ +#if defined(__LINUX__) + chan=(private_area_t*)wan_netif_priv(chan->common.dev); + + if (!card->u.aft.tdmv_api_rx){ + /* CRITICAL ERROR: + * There should be an rx api packet here */ + goto wp_tdmv_api_rx_tx_skip_rx; + } + + if (wan_skb_len(card->u.aft.tdmv_api_rx) != card->u.aft.tdmv_mtu){ + wan_skb_free(card->u.aft.tdmv_api_rx); + card->u.aft.tdmv_api_rx=NULL; + goto wp_tdmv_api_rx_tx_skip_rx; + } + + if (wan_skb_headroom(card->u.aft.tdmv_api_rx) >= sizeof(api_rx_hdr_t)){ + api_rx_hdr_t *rx_hdr= + (api_rx_hdr_t*)skb_push(card->u.aft.tdmv_api_rx, + sizeof(api_rx_hdr_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + }else{ + wan_skb_free(card->u.aft.tdmv_api_rx); + card->u.aft.tdmv_api_rx=NULL; + goto wp_tdmv_api_rx_tx_skip_rx; + } + + card->u.aft.tdmv_api_rx->protocol = htons(PVC_PROT); + wan_skb_reset_mac_header(card->u.aft.tdmv_api_rx); + card->u.aft.tdmv_api_rx->dev = chan->common.dev; + card->u.aft.tdmv_api_rx->pkt_type = WAN_PACKET_DATA; + + if (wan_api_rx(chan,card->u.aft.tdmv_api_rx) != 0){ + wan_skb_free(card->u.aft.tdmv_api_rx); + } + + card->u.aft.tdmv_api_rx=NULL; + +wp_tdmv_api_rx_tx_skip_rx: + + if (card->u.aft.tdmv_api_tx){ + + if (wan_skb_len(card->u.aft.tdmv_api_tx) != 0){ + /*CRITICAL ERROR: + * Length must be zero, because we pulled + * all timeslots out*/ + } + + wan_skb_free(card->u.aft.tdmv_api_tx); + card->u.aft.tdmv_api_tx=NULL; + + if (WAN_NETIF_QUEUE_STOPPED(chan->common.dev)){ + WAN_NETIF_WAKE_QUEUE(chan->common.dev); + wan_wakeup_api(chan); + } + } +#endif + return; +} +#endif + +#if defined(__LINUX__) +/*============================================= + * aft_set_ss7_force_rx + * + * Force the firmware to pass up a single + * ss7 packet. Otherwise, the ss7 engine + * will wait for the next different packet. + */ +static void aft_set_ss7_force_rx(sdla_t *card, private_area_t *chan) +{ + u32 reg, dma_ram_desc; + + if (wan_test_and_set_bit(0,&chan->ss7_force_rx)){ + DEBUG_TEST("%s: FORCE BUSY RX\n",card->devname); + return; + } + + dma_ram_desc=chan->logic_ch_num*4+AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + if (wan_test_bit(AFT_DMACHAIN_SS7_FORCE_RX,®)){ + wan_clear_bit(AFT_DMACHAIN_SS7_FORCE_RX,®); + }else{ + wan_set_bit(AFT_DMACHAIN_SS7_FORCE_RX,®); + } + card->hw_iface.bus_write_4(card->hw,dma_ram_desc,reg); + + DEBUG_TEST("%s: FORCE RX\n",card->devname); +} +#endif + +/*============================================= + * aft_clear_ss7_force_rx + * + * Reset the ss7 force rx logic. + * This must be done before trying to enable + * force rx again. + * Note: That first_time_slot must be cleared LAST. + * Thus the reverse clear order. + */ +static void aft_clear_ss7_force_rx(sdla_t *card, private_area_t *chan) +{ + wan_clear_bit(0,&chan->ss7_force_rx); +} + + +#if defined(AFT_API_SUPPORT) || defined(AFT_TDM_API_SUPPORT) +static int aft_event_ctrl(void *chan_ptr, wan_event_ctrl_t *p_event) +{ + sdla_t *card = NULL; + private_area_t *chan = (private_area_t *)chan_ptr; + wan_event_ctrl_t *event_ctrl; + int err = -EINVAL; + + card = chan->card; + event_ctrl = wan_malloc(sizeof(wan_event_ctrl_t)); + if (event_ctrl == NULL){ + DEBUG_EVENT("%s: Failed to allocate event control!\n", + card->devname); + return -EFAULT; + } + memset(event_ctrl, 0, sizeof(wan_event_ctrl_t)); + memcpy(event_ctrl, p_event, sizeof(wan_event_ctrl_t)); + + if (event_ctrl->type == WAN_EVENT_EC_DTMF && card->wandev.ec_dev){ +#if defined(CONFIG_WANPIPE_HWEC) + DEBUG_TEST("%s: Event control request EC_DTMF...\n", + chan->if_name); + err = wanpipe_ec_event_ctrl(card->wandev.ec_dev, card, event_ctrl); +#endif + }else if (chan->card->wandev.fe_iface.event_ctrl){ + + DEBUG_TEST("%s: FE Event control request...\n", + chan->if_name); + err = chan->card->wandev.fe_iface.event_ctrl( + &chan->card->fe, event_ctrl); + }else{ + DEBUG_TEST("%s: Unsupported event control request (%lX)\n", + chan->if_name, event_ctrl->type); + } + if (err){ + if (event_ctrl) wan_free(event_ctrl); + } + return err; +} +#endif + +#ifdef AFT_TDM_API_SUPPORT +static int aft_read_rbs_bits(void *chan_ptr, u32 ch, u8 *rbs_bits) +{ + private_area_t *chan = (private_area_t *)chan_ptr; + wan_smp_flag_t flags; + + if (!chan_ptr){ + return -EINVAL; + } + + chan->card->hw_iface.hw_lock(chan->card->hw,&flags); + *rbs_bits = chan->card->wandev.fe_iface.read_rbsbits( + &chan->card->fe, + chan->logic_ch_num+1, + WAN_TE_RBS_UPDATE); + chan->card->hw_iface.hw_unlock(chan->card->hw,&flags); + + return 0; + +} + +static int aft_write_rbs_bits(void *chan_ptr, u32 ch, u8 rbs_bits) +{ + private_area_t *chan = (private_area_t *)chan_ptr; + wan_smp_flag_t flags; + int err; + + if (!chan_ptr){ + return -EINVAL; + } + + chan->card->hw_iface.hw_lock(chan->card->hw,&flags); + err = chan->card->wandev.fe_iface.set_rbsbits(&chan->card->fe, + chan->logic_ch_num+1, + rbs_bits); + chan->card->hw_iface.hw_unlock(chan->card->hw,&flags); + + return err; +} + + +static int aft_write_hdlc_frame(void *chan_ptr, netskb_t *skb) +{ + private_area_t *chan = (private_area_t *)chan_ptr; + sdla_t *card=chan->card; + wan_smp_flag_t smp_flags; + int err=-EINVAL; + + if (!chan_ptr || !chan->common.dev || !card){ + WAN_ASSERT(1); + return -EINVAL; + } + + if (wan_skb_len(skb) > chan->mtu) { + return -EINVAL; + } + + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + + if (wan_skb_queue_len(&chan->wp_tx_pending_list) > chan->max_tx_bufs){ + aft_dma_tx(card,chan); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + return -EBUSY; + + } + + wan_skb_unlink(skb); + wan_skb_queue_tail(&chan->wp_tx_pending_list,skb); + aft_dma_tx(card,chan); + + + err=0; + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + + + + return err; +} +#endif + + +static int aft_tdm_ring_rsync(sdla_t *card) +{ + int i; + private_area_t *chan; + for (i=0; iu.aft.num_of_time_slots;i++){ + + if (!wan_test_bit(i,&card->u.aft.tdm_logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + DEBUG_EVENT("%s: Error: No Dev for Rx logical ch=%d\n", + card->devname,i); + continue; + } + + if (chan->channelized_cfg && !chan->hdlc_eng && chan->cfg.tdmv_master_if){ + + u32 lo_reg; + u32 dma_descr=(chan->logic_ch_num<<4) + + AFT_PORT_REG(card,AFT_RX_DMA_LO_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,&lo_reg); + + lo_reg=(lo_reg&AFT_TDMV_BUF_MASK)/AFT_TDMV_CIRC_BUF; + + if (card->wandev.ec_enable){ + /* HW EC standard */ + if (lo_reg > 0) { + card->u.aft.tdm_rx_dma_toggle = lo_reg-1; + } else { + card->u.aft.tdm_rx_dma_toggle = 3; + } + } else { + /* Software ec moves spike to 8bytes */ + card->u.aft.tdm_rx_dma_toggle=lo_reg+1; + if (card->u.aft.tdm_rx_dma_toggle > 3) { + card->u.aft.tdm_rx_dma_toggle=0; + } + } + + if (lo_reg < 3) { + card->u.aft.tdm_tx_dma_toggle = lo_reg+1; + } else { + card->u.aft.tdm_tx_dma_toggle = 0; + } + + card->rsync_timeout=0; + DEBUG_EVENT("%s: Card TDM Rsync Rx=%i Tx=%i\n", + card->devname, + card->u.aft.tdm_rx_dma_toggle, + card->u.aft.tdm_tx_dma_toggle); + } + } + + return 0; +} + +static void aft_critical_event (void *arg, int type) +{ + sdla_t *card = (sdla_t*)arg; + DEBUG_EVENT("%s: Error: Card Critically Shutdown: Short Circuit Detected!\n", + card->devname); + aft_critical_shutdown(card); + return; +} + +static void aft_critical_shutdown (sdla_t *card) +{ + DEBUG_EVENT("%s: Error: Card Critically Shutdown!\n", + card->devname); + + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + if (card->wandev.fe_iface.unconfig){ + card->wandev.fe_iface.unconfig(&card->fe); + } + disable_data_error_intr(card,DEVICE_DOWN); + wan_set_bit(CARD_DOWN,&card->wandev.critical); + port_set_state(card,WAN_DISCONNECTED); + + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_ON); + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_OFF); +} + +enum { + WAN_TDM_RTP_NO_CHANGE, + WAN_TDM_RTP_CALL_START, + WAN_TDM_RTP_CALL_STOP +}; + + +static int aft_hwec_config (sdla_t *card, private_area_t *chan, wanif_conf_t *conf, int ctrl) +{ + int err = 0; + unsigned int channel=0; + unsigned int tdmv_hwec_option=0; + + if (conf) { + tdmv_hwec_option=conf->hwec.enable; + } + + if (chan->common.usedby == TDM_VOICE_API || + chan->common.usedby == TDM_VOICE){ + + if (IS_TE1_CARD(card)) { + if (IS_T1_CARD(card)){ + channel = chan->first_time_slot; + }else{ + channel = chan->first_time_slot; + } + } else { + channel = chan->first_time_slot; + } + +#if defined(CONFIG_WANPIPE_HWEC) + if (ctrl == 0 && card->wandev.ec_enable){ + card->wandev.ec_enable(card, 0, channel); + + } else if (tdmv_hwec_option && card->wandev.ec_enable){ + DEBUG_HWEC("%s: HW echo canceller Enabled on channel %d\n", + chan->if_name, + channel); + err = card->wandev.ec_enable(card, 1, channel); + if (err) { + DEBUG_EVENT("%s: Failed to enable HWEC on channel %d\n", + chan->if_name,channel); + return err; + } + } +#endif + } + + return err; + +} + + +#if defined(__LINUX__) + +static void aft_rtp_unconfig(sdla_t *card) +{ + netskb_t *skb; + + card->u.aft.cfg.rtp_ip=0; + card->u.aft.cfg.rtp_sample=0; + card->u.aft.rtp_len=0; + if (card->u.aft.rtp_dev) { + dev_put(card->u.aft.rtp_dev); + card->u.aft.rtp_dev=NULL; + } + + if ((skb=card->u.aft.rx_rtp_skb)) { + card->u.aft.rx_rtp_skb=NULL; + wan_skb_free(skb); + } + +} + +static void aft_rtp_config(sdla_t *card) +{ + +/* RTP TAP Not finished yet */ + return; + + +#if 0 + if (!card->u.aft.cfg.rtp_ip || !card->u.aft.cfg.rtp_sample) { + goto aft_rtp_init_exit; + } + + switch (card->u.aft.cfg.rtp_sample) { + case 10: + case 20: + case 30: + case 40: + /* Supported Sample Sizes */ + break; + default: + goto aft_rtp_init_exit; + } +#endif + + card->u.aft.cfg.rtp_port=9000; + card->u.aft.cfg.rtp_ip=0x0100007F; + card->u.aft.cfg.rtp_sample=100; + card->u.aft.rtp_len = (card->u.aft.cfg.rtp_sample * 8) + sizeof(wan_rtp_pkt_t); + sprintf(card->u.aft.cfg.rtp_devname,"lo"); + + if ((card->u.aft.rtp_dev=dev_get_by_name(card->u.aft.cfg.rtp_devname)) == NULL){ + DEBUG_EVENT("%s: Failed to open rtp tx device %s\n", + card->devname, + card->u.aft.cfg.rtp_devname); + goto aft_rtp_init_exit; + } + + DEBUG_EVENT("%s: Configured rtp tap!\n",card->devname); + return; + +aft_rtp_init_exit: + + aft_rtp_unconfig(card); + + DEBUG_EVENT("%s: Failed to configure rtp tap!\n",card->devname); + return; + +} + + +#if 0 +static void aft_rtp_tap(sdla_t *card, private_area_t *chan, u8* rx, u8* tx, u32 len) +{ + wan_rtp_pkt_t *pkt; + u8 *buf; + netskb_t *skb; + u32 ecmap, call_status=WAN_TDM_RTP_NO_CHANGE; + + if (!card->u.aft.cfg.rtp_ip || + !card->u.aft.cfg.rtp_sample || + !card->u.aft.rtp_len || + !card->u.aft.rtp_dev) { + return; + } + + if (IS_T1_CARD(card)) { + ecmap=card->wandev.ec_map; + } else { + ecmap=card->wandev.ec_map << 1; + } + + if (1) { //wan_test_bit(chan->first_time_slot,&ecmap)) { + if (!wan_test_and_set_bit(0,&chan->tdm_call_status)) { + /* Start of the call */ + call_status=WAN_TDM_RTP_CALL_START; + DEBUG_TEST("%s: CALL Start on ch %i\n", + chan->if_name,chan->first_time_slot); + } + } else { + if (!wan_test_bit(0,&chan->tdm_call_status)) { + /* Call not up */ + return; + } + call_status=WAN_TDM_RTP_CALL_STOP; + DEBUG_TEST("%s: CALL Stop on ch %i\n", + chan->if_name,chan->first_time_slot); + } + + + if (!(skb=chan->rx_rtp_skb)) { + card->u.aft.rtp_len = (card->u.aft.cfg.rtp_sample * 8) + sizeof(wan_rtp_pkt_t); + chan->rx_rtp_skb=wan_skb_alloc(card->u.aft.rtp_len+128); + if (!chan->rx_rtp_skb) { + return; + } + skb=chan->rx_rtp_skb; + pkt = (wan_rtp_pkt_t*)wan_skb_put(skb,sizeof(wan_rtp_pkt_t)); + memset(pkt,0,sizeof(wan_rtp_pkt_t)); + pkt->rtp_hdr.version=2; + if (IS_T1_CARD(card)) { + pkt->rtp_hdr.pt=0; + } else { + pkt->rtp_hdr.pt=1; + } + } + + pkt = (wan_rtp_pkt_t*)wan_skb_data(skb); + + if (call_status == WAN_TDM_RTP_CALL_START) { + pkt->rtp_hdr.seq=0; + pkt->rtp_hdr.ts=0; + } + + buf=wan_skb_put(skb,len); + memcpy(buf,rx,len); + pkt->rtp_hdr.ts++; + + if (wan_skb_len(skb) >= card->u.aft.rtp_len || + call_status==WAN_TDM_RTP_CALL_STOP) { + netskb_t *nskb; + wan_ip_udp_setup(card, + card->u.aft.cfg.rtp_ip, + card->u.aft.cfg.rtp_port+chan->first_time_slot, + wan_skb_data(skb), + wan_skb_len(skb)-sizeof(wan_rtp_pkt_t)); + nskb=wan_skb_clone(skb); + if (nskb) { + nskb->next = nskb->prev = NULL; + nskb->dev = card->u.aft.rtp_dev; + nskb->protocol = htons(ETH_P_802_2); + wan_skb_reset_mac_header(nskb); + //wan_skb_reset_network_header(nskb); + dev_queue_xmit(nskb); + } + wan_skb_trim(skb,sizeof(wan_rtp_pkt_t)); + pkt->rtp_hdr.seq++; + + #if 0 + /* Disable rtp (debugging) */ + card->u.aft.rtp_len=0; + #endif + + } +} +#endif +#endif + + +static int aft_find_master_if_and_dchan(sdla_t *card, int *master_if, u32 active_ch) +{ + int dchan_found=0; + int i; + + if (card->tdmv_conf.dchan) { + if (IS_E1_CARD(card) && !(WAN_FE_FRAME(&card->fe) == WAN_FR_UNFRAMED)) { + card->tdmv_conf.dchan = card->tdmv_conf.dchan << 1; + wan_clear_bit(0,&card->tdmv_conf.dchan); + } + } + + for (i=card->u.aft.num_of_time_slots-1;i>=0;i--){ + if (wan_test_bit(i,&active_ch)){ + + if (wan_test_bit(i,&card->tdmv_conf.dchan)){ + dchan_found=1; + card->u.aft.tdmv_dchan=i; + continue; + } + + /* Find the TOP timeslot. This timeslot will be + * considered MASTER since it is the last timeslot + * to rx data from the T1 line */ + if (*master_if < 0){ + *master_if=i; + } + } + } + + if (card->tdmv_conf.dchan && !dchan_found){ + /* We configured for dchan however, this interface + * was not configued with the DCHAN timeslot. + * It IS now possible that another interface has + * this time slot */ + for (i=card->u.aft.num_of_time_slots-1;i>=0;i--){ + if (wan_test_bit(i,&card->tdmv_conf.dchan)){ + dchan_found=1; + card->u.aft.tdmv_dchan=i; + wan_set_bit(i,&card->u.aft.tdmv_dchan_cfg_on_master); + continue; + } + } + + if (!dchan_found) { + DEBUG_EVENT("%s: Error: TDM DCHAN is out of range 0x%08X\n", + card->devname,card->tdmv_conf.dchan); + return -EINVAL; + } + + /* We have found a DCHAN outside the + Voice active channels */ + } + + return 0; +} + + +static int digital_loop_test(sdla_t* card,wan_udp_pkt_t* wan_udp_pkt) +{ + netskb_t* skb; + netdevice_t* dev; + char* buf; + private_area_t *chan; + + dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head)); + if (dev == NULL) { + return 1; + } + chan = wan_netif_priv(dev); + if (chan == NULL) { + return 1; + } + + if (chan->common.state != WAN_CONNECTED) { + DEBUG_EVENT("%s: Loop test failed: dev not connected!\n", + card->devname); + return 2; + } + + skb = wan_skb_alloc(wan_udp_pkt->wan_udp_data_len+100); + if (skb == NULL) { + return 3; + } + + switch (chan->common.usedby) { + + case API: + wan_skb_push(skb, sizeof(api_rx_hdr_t)); + break; + + case STACK: + case WANPIPE: + break; + + case TDM_VOICE: + case TDM_VOICE_API: + case TDM_VOICE_DCHAN: + if (card->u.aft.tdmv_dchan) { + break; + } else { + DEBUG_EVENT("%s: Loop test failed: no dchan in TDMV mode!\n", + card->devname); + } + /* Fall into the default case */ + + default: + DEBUG_EVENT("%s: Loop test failed: invalid operation mode!\n", + card->devname); + wan_skb_free(skb); + return 4; + } + + buf = wan_skb_put(skb, wan_udp_pkt->wan_udp_data_len); + memcpy(buf, wan_udp_pkt->wan_udp_data, wan_udp_pkt->wan_udp_data_len); + + + skb->next = skb->prev = NULL; + skb->dev = dev; + skb->protocol = htons(ETH_P_IP); + wan_skb_reset_mac_header(skb); + dev_queue_xmit(skb); + + return 0; +} +/****** End ****************************************************************/ diff --git a/patches/kdrivers/src/net/sdla_aft_te3.c b/patches/kdrivers/src/net/sdla_aft_te3.c index 53f9b99..5e28d97 100644 --- a/patches/kdrivers/src/net/sdla_aft_te3.c +++ b/patches/kdrivers/src/net/sdla_aft_te3.c @@ -1285,7 +1285,8 @@ static int if_open (netdevice_t* dev) * how long has the interface been up */ wan_getcurrenttime(&chan->router_start_time, NULL); - WAN_NETIF_START_QUEUE(dev); + WAN_NETIF_STOP_QUEUE(dev); + WAN_NETIF_CARRIER_OFF(dev); /* If FRONT End is down, it means that the DMA * is disabled. In this case don't try to diff --git a/patches/kdrivers/src/net/sdla_bitstrm.c b/patches/kdrivers/src/net/sdla_bitstrm.c index ca979c2..06eac80 100644 --- a/patches/kdrivers/src/net/sdla_bitstrm.c +++ b/patches/kdrivers/src/net/sdla_bitstrm.c @@ -1654,6 +1654,11 @@ static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) card->u.b.cfg.max_length_tx_data_block = 682;//divisible by 31 card->u.b.time_slots = NO_ACTIVE_RX_TIME_SLOTS_E1; } + + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -1985,6 +1990,9 @@ static void disable_comm (sdla_t *card) /* TE1 - Unconfiging */ if (IS_TE1_CARD(card)) { + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -5049,7 +5057,9 @@ static int config_bstrm (sdla_t *card) (IS_T1_CARD(card))?"T1":"E1"); return -EINVAL; } - + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } @@ -5066,6 +5076,9 @@ static int config_bstrm (sdla_t *card) card->devname); return -EINVAL; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } if (card->u.b.serial){ diff --git a/patches/kdrivers/src/net/sdla_chdlc.c b/patches/kdrivers/src/net/sdla_chdlc.c index 918d37a..3d3c4cd 100644 --- a/patches/kdrivers/src/net/sdla_chdlc.c +++ b/patches/kdrivers/src/net/sdla_chdlc.c @@ -1392,6 +1392,10 @@ static void disable_comm (sdla_t *card) /* TE1 - Unconfiging, only on shutdown */ if (IS_TE1_CARD(card)) { + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -1902,6 +1906,10 @@ static int chdlc_disable_comm_shutdown (sdla_t *card) /* TE1 - Unconfiging, only on shutdown */ if (IS_TE1_CARD(card)) { + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -4255,6 +4263,10 @@ static int config_chdlc (sdla_t *card, netdevice_t *dev) (IS_T1_CARD(card))?"T1":"E1"); return -EINVAL; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } + } @@ -4271,6 +4283,9 @@ static int config_chdlc (sdla_t *card, netdevice_t *dev) card->devname); return -EINVAL; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } diff --git a/patches/kdrivers/src/net/sdla_fr.c b/patches/kdrivers/src/net/sdla_fr.c index 8ff139a..91d0cc5 100644 --- a/patches/kdrivers/src/net/sdla_fr.c +++ b/patches/kdrivers/src/net/sdla_fr.c @@ -846,6 +846,10 @@ int wpf_init(sdla_t *card, wandev_conf_t *conf) (IS_T1_CARD(card))?"T1":"E1"); return -EIO; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } + }else if (IS_56K_CARD(card)) { int err = -EINVAL; @@ -860,6 +864,9 @@ int wpf_init(sdla_t *card, wandev_conf_t *conf) card->devname); return -EIO; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } @@ -1424,6 +1431,10 @@ static void disable_comm (sdla_t *card) /* TE1 unconfiging */ if (IS_TE1_CARD(card)) { + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } diff --git a/patches/kdrivers/src/net/sdla_ppp.c b/patches/kdrivers/src/net/sdla_ppp.c index b5cacf2..9fb68c1 100644 --- a/patches/kdrivers/src/net/sdla_ppp.c +++ b/patches/kdrivers/src/net/sdla_ppp.c @@ -865,6 +865,10 @@ static void disable_comm (sdla_t *card) /* TE1 unconfiging */ if (IS_TE1_CARD(card)) { + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -3817,6 +3821,9 @@ static int config_ppp (sdla_t *card) (IS_T1_CARD(card))?"T1":"E1"); return 0; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } }else if (IS_56K_CARD(card)) { int err = -EINVAL; @@ -3831,6 +3838,9 @@ static int config_ppp (sdla_t *card) card->devname); return 0; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } diff --git a/patches/kdrivers/src/net/sdla_tdmv.c b/patches/kdrivers/src/net/sdla_tdmv.c index 21e050a..8c7389e 100644 --- a/patches/kdrivers/src/net/sdla_tdmv.c +++ b/patches/kdrivers/src/net/sdla_tdmv.c @@ -77,6 +77,20 @@ #define WP_TDMV_ENABLE 0x01 #define WP_TDMV_DISABLE 0x02 +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) +# define IS_CHAN_HARDHDLC(chan) (((chan)->flags & ZT_FLAG_NOSTDTXRX) || ((chan)->flags & ZT_FLAG_HDLC)) +#else +# define IS_CHAN_HARDHDLC(chan) ((chan)->flags & ZT_FLAG_HDLC) +#endif + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) +# if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) +# undef ZT_DCHAN_TX +# endif +#else +#warning "TDM VOICE DCHAN DISABLED" +#endif + #if defined(__FreeBSD__) extern short *__zt_mulaw; #endif @@ -218,6 +232,9 @@ static int wp_tdmv_ioctl(struct zt_chan*, unsigned int, unsigned long); #endif static int wp_tdmv_hwec(struct zt_chan *chan, int enable); +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) +static void wp_tdmv_tx_hdlc_hard(struct zt_chan *chan); +#endif static int wp_tdmv_state(void* pcard, int state); static int wp_tdmv_running(void* pcard); @@ -238,8 +255,10 @@ static int wp_tdmv_rx_tx_span(void *pcard); static int wp_tdmv_span_buf_rotate(void *pcard, u32, unsigned long); static int wp_tdmv_ec_span(void *pcard); static int wp_tdmv_rx_chan(wan_tdmv_t*, int, unsigned char*, unsigned char*); -#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(ZT_DCHAN_TX) static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len); +#endif +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) static int wp_tdmv_rx_dchan(wan_tdmv_t*, int, unsigned char*, unsigned int); #endif static int wp_tdmv_rxcopy(wan_tdmv_t *wan_tdmv, unsigned char* rxbuf, int max_len); @@ -1047,20 +1066,29 @@ static int wp_tdmv_software_init(wan_tdmv_t *wan_tdmv) wp->span.channels = wp->max_timeslots; wp->span.chans = wp->chans; wp->span.flags = ZT_FLAG_RBS; - wp->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF; + wp->span.ioctl = wp_tdmv_ioctl; /* Set this pointer only if card has hw echo canceller module */ if (wp->hwec == WANOPT_YES && card->wandev.ec_dev){ /* Initialize it only if HWEC option is enabled */ wp->span.echocan = wp_tdmv_hwec; } +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) + if (wp->dchan_map){ + DEBUG_EVENT("%s: Enable Zaptel HW DCHAN interface\n", + wp->devname); + wp->span.hdlc_hard_xmit = wp_tdmv_tx_hdlc_hard; + } +#endif wp->span.pvt = wp; if (wp->ise1){ wp->span.deflaw = ZT_LAW_ALAW; card->fe.fe_cfg.tdmv_law = WAN_TDMV_ALAW; + wp->span.linecompat = ZT_CONFIG_HDB3 | ZT_CONFIG_CCS | ZT_CONFIG_CRC4; }else{ wp->span.deflaw = ZT_LAW_MULAW; card->fe.fe_cfg.tdmv_law = WAN_TDMV_MULAW; + wp->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF; } #if !defined(__FreeBSD__) && !defined(__OpenBSD__) init_waitqueue_head(&wp->span.maintq); @@ -1077,7 +1105,11 @@ static int wp_tdmv_software_init(wan_tdmv_t *wan_tdmv) ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS | - ZT_SIG_CAS | ZT_SIG_DACS_RBS; + ZT_SIG_CAS | ZT_SIG_DACS_RBS +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) + | ZT_SIG_HARDHDLC +#endif + ; }else{ wp->chans[x].sigcap = ZT_SIG_NONE; } @@ -1516,9 +1548,10 @@ static int wp_tdmv_rbsbits(struct zt_chan *chan, int bits) if (bits & ZT_CBIT) ABCD_bits |= WAN_RBS_SIG_C; if (bits & ZT_DBIT) ABCD_bits |= WAN_RBS_SIG_D; - if (chan->flags & ZT_FLAG_HDLC){ - return 0; - } + if (IS_CHAN_HARDHDLC(chan)){ + return 0; + } + DEBUG_TDMV( "[TDMV] %s: %s:%02d(%d) TX RBS: A:%1d B:%1d C:%1d D:%1d\n", wp->devname, @@ -1755,17 +1788,19 @@ wp_tdmv_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) #endif { int err = -ENOTTY; -#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) - wp_tdmv_softc_t *wp = NULL; -#endif + wp_tdmv_softc_t *wp=NULL; + #ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER wp_tdmv_softc_t *echo_detect_wp = NULL; int echo_detect_chan = 0; #endif + wp = chan->pvt; + switch(cmd) { -#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(ZT_DCHAN_TX) case ZT_DCHAN_TX: WAN_ASSERT(chan == NULL || chan->pvt == NULL); @@ -1859,7 +1894,7 @@ static int wp_tdmv_hwec(struct zt_chan *chan, int enable) * echo cancellation is enabled regardless of * asterisk. In persist mode off asterisk * controls hardware echo cancellation */ - if (card->hwec_conf.persist_disable || chan->flags & ZT_FLAG_HDLC) { + if (card->hwec_conf.persist_disable || IS_CHAN_HARDHDLC(chan)) { err = card->wandev.ec_enable(card, enable, channel); } else { err = 0; @@ -1989,7 +2024,8 @@ static int wp_tdmv_rx_dchan(wan_tdmv_t *wan_tdmv, int channo, wp->devname); return -EINVAL; } - if (!(ms->flags & ZT_FLAG_HDLC)){ + + if (!IS_CHAN_HARDHDLC(ms)){ DEBUG_TDMV("%s: ERROR: %s not defined as D-CHAN!\n", wp->devname, ms->name); return -EINVAL; @@ -2060,7 +2096,41 @@ static int wp_tdmv_rx_dchan(wan_tdmv_t *wan_tdmv, int channo, } #endif -#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) + + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) +static void wp_tdmv_tx_hdlc_hard(struct zt_chan *chan) +{ + wp_tdmv_softc_t *wp = NULL; + netskb_t *skb = NULL; + unsigned char *data = NULL; + int size = 0, err = 0, res = 0; + + WAN_ASSERT_VOID(chan == NULL); + WAN_ASSERT_VOID(chan->pvt == NULL); + wp = chan->pvt; + WAN_ASSERT_VOID(wp->dchan_dev == NULL); + + size = chan->writen[chan->outwritebuf] - chan->writeidx[chan->outwritebuf]-2; + skb = wan_skb_alloc(size+1); + if (skb == NULL){ + return; + } + data = wan_skb_put(skb, size); + res = zt_hdlc_getbuf(chan, data, &size); + if (res == 0){ + DEBUG_EVENT("%s: ERROR: TX HW DCHAN %d bytes (res %d)\n", + wp->devname, size, res); + } + err = wp->dchan_dev->hard_start_xmit(skb, wp->dchan_dev); + if (err){ + wan_skb_free(skb); + } + return; +} +#endif + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(ZT_DCHAN_TX) static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len) { wp_tdmv_softc_t *wp = NULL; @@ -2073,11 +2143,13 @@ static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len) WAN_ASSERT2(chan->pvt == NULL, -ENODEV); wp = chan->pvt; WAN_ASSERT(wp->dchan_dev == NULL); + if (len <= 2){ return -EINVAL; } len -= 2; /* Remove checksum */ + skb = wan_skb_alloc(len+1); if (skb == NULL){ return -ENOMEM; @@ -2108,6 +2180,7 @@ static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len) #endif + /****************************************************************************** ** wp_tdmv_rx_chan() - ** diff --git a/patches/kdrivers/src/net/sdla_tdmv.c~ b/patches/kdrivers/src/net/sdla_tdmv.c~ new file mode 100644 index 0000000..914c320 --- /dev/null +++ b/patches/kdrivers/src/net/sdla_tdmv.c~ @@ -0,0 +1,2409 @@ +/*************************************************************************** + * sdla_tdmv.c WANPIPE(tm) Multiprotocol WAN Link Driver. + * TDM voice board configuration. + * + * Author: Alex Feldman + * Nenad Corbic + * David Rokvargh + * + * Copyright: (c) 1995-2005 Sangoma Technologies Inc. + * + * 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. + * ============================================================================ + * Jul 22, 2001 Nenad Corbic Initial version. + * Oct 01, 2001 Gideon Hack Modifications for interrupt usage. + * Aug 9, 2005 David Rokhvarg Added Echo Detection and Control (EDAC). + ****************************************************************************** + */ +/* + **********CONFIGURING******************************************************************** + INCLUDE FILES + ****************************************************************************** +*/ + +#if defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +# include +# include +# include +# include /* WANPIPE TDM Voice definitions */ +# include +#elif (defined __WINDOWS__) +# include +#else +# include +# include +# include +# include +# include /* WANPIPE TDM Voice definitions */ +#endif + +/* + ****************************************************************************** + DEFINES AND MACROS + ****************************************************************************** +*/ +#define DEBUG_ECHO if(0) DEBUG_EVENT + +#define WP_MAX_CARDS 32 + +#define FIXME_MSG(func) DEBUG_EVENT("(%s): FIXME: line %d\n", func, __LINE__) +#define DBG_FUNC_START(func) DEBUG_EVENT("(DEBUG)(TDM Voice): %s - Start\n", func) +#define DBG_FUNC_END(func) DEBUG_EVENT("(DEBUG)(TDM Voice): %s - End\n", func) + +/* flags bits */ +#define WP_TDMV_REGISTER 1 /*0x01*/ +#define WP_TDMV_RUNNING 2 /*0x02*/ +#define WP_TDMV_UP 3 /*0x04*/ +#define WP_TDMV_SIG_ENABLE 4 /*0x08*/ +#define WP_TDMV_SIG_POLL 5 /*0x10*/ +#define WP_TDMV_RBS_READY 6 /*0x20*/ +#define WP_TDMV_RBS_BUSY 7 /*0x40*/ +#define WP_TDMV_RBS_UPDATE 8 /*0x80*/ + +#define IS_TDMV_RUNNING(wp) wan_test_bit(WP_TDMV_RUNNING, &(wp)->flags) +#define IS_TDMV_UP(wp) wan_test_bit(WP_TDMV_UP, &(wp)->flags) +#define IS_TDMV_SIG_POLL(wp) wan_test_bit(WP_TDMV_SIG_POLL, &(wp)->flags) +#define IS_TDMV_SIG_ENABLE(wp) wan_test_bit(WP_TDMV_SIG_ENABLE, &(wp)->flags) +#define IS_TDMV_UP_RUNNING(wp) (IS_TDMV_UP(wp) && IS_TDMV_RUNNING(wp)) +#define IS_TDMV_SIG(wp) (IS_TDMV_SIG_POLL(wp) && IS_TDMV_SIG_ENABLE(wp)) +#define IS_TDMV_RBS_READY(wp) wan_test_bit(WP_TDMV_RBS_READY, &(wp)->flags) + +#define WP_TDMV_ENABLE 0x01 +#define WP_TDMV_DISABLE 0x02 + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) +# define IS_CHAN_HARDHDLC(chan) (((chan)->flags & ZT_FLAG_NOSTDTXRX) || ((chan)->flags & ZT_FLAG_HDLC)) +#else +# define IS_CHAN_HARDHDLC(chan) ((chan)->flags & ZT_FLAG_HDLC) +#endif + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) +# if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) +# undef ZT_DCHAN_TX +# endif +#else +#warning "TDM VOICE DCHAN DISABLED" +#endif + +#if defined(__FreeBSD__) +extern short *__zt_mulaw; +#endif + + +#if 0 +static unsigned char wp_tdmv_ulaw[] = { + 0, 0, 0, 0, 0, 1, 1, 1, + 1, 2, 2, 2, 2, 3, 3, 3, + 3, 4, 4, 4, 4, 5, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 11, 11, 11, + 11, 12, 12, 12, 12, 13, 13, 13, + 13, 14, 14, 14, 14, 15, 15, 15, + 15, 16, 16, 17, 17, 18, 18, 19, + 19, 20, 20, 21, 21, 22, 22, 23, + 23, 24, 24, 25, 25, 26, 26, 27, + 27, 28, 28, 29, 29, 30, 30, 31, + 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, + 47, 49, 51, 53, 55, 57, 59, 61, + 63, 66, 70, 74, 78, 84, 92, 104, + 254, 231, 219, 211, 205, 201, 197, 193, + 190, 188, 186, 184, 182, 180, 178, 176, + 175, 174, 173, 172, 171, 170, 169, 168, + 167, 166, 165, 164, 163, 162, 161, 160, + 159, 159, 158, 158, 157, 157, 156, 156, + 155, 155, 154, 154, 153, 153, 152, 152, + 151, 151, 150, 150, 149, 149, 148, 148, + 147, 147, 146, 146, 145, 145, 144, 144, + 143, 143, 143, 143, 142, 142, 142, 142, + 141, 141, 141, 141, 140, 140, 140, 140, + 139, 139, 139, 139, 138, 138, 138, 138, + 137, 137, 137, 137, 136, 136, 136, 136, + 135, 135, 135, 135, 134, 134, 134, 134, + 133, 133, 133, 133, 132, 132, 132, 132, + 131, 131, 131, 131, 130, 130, 130, 130, + 129, 129, 129, 129, 128, 128, 128, 128, +}; +#endif + +/* + ****************************************************************************** + STRUCTURES AND TYPEDEFS + ****************************************************************************** +*/ +typedef struct wp_tdmv_pvt_area +{ + sdla_t* card; + char* devname; + wan_spinlock_t lock; + wan_spinlock_t tx_rx_lock; + int ise1; + int num; + int spanno; + int flags; + int lbo; + int lcode; + int frame; + int usecount; + int sync; + int blinktimer; + int alarmtimer; + int loopupcnt; + int loopdowncnt; +#ifdef FANCY_ALARM + int alarmpos; +#endif + /* T1 signalling */ + struct zt_span span; /* Span */ + struct zt_chan chans[31]; /* Channels */ + unsigned char ec_chunk1[31][ZT_CHUNKSIZE]; + unsigned char ec_chunk2[31][ZT_CHUNKSIZE]; + unsigned long config_tsmap; + unsigned long timeslot_map; + int max_timeslots; /* T1: 24, E1: 31 */ + int timeslots; /* configured timeslots */ + unsigned long sig_timeslot_map; + int sig_timeslots; + unsigned long rbs_tx_status; + unsigned long rbs_tx1_status; + unsigned char rbs_tx[31]; + unsigned char rbs_tx1[31]; + unsigned char rbs_rx[31]; + unsigned long rbs_rx_pending; + u32 intcount; + u32 rbscount; + unsigned int brt_ctrl; + unsigned char hwec; + unsigned char echo_off; + unsigned long echo_off_map; + unsigned int max_rxtx_len; + + unsigned int channelized; /* WAN_TRUE or WAN_FALSE */ + unsigned char *tx_unchan; /* tx data pointer for unchannelized mode */ + + /* AHDLC: Hardware HDLC arguments */ + unsigned int dchan_map; + netdevice_t *dchan_dev; + +} wp_tdmv_softc_t; + + + +/* +******************************************************************************* +** GLOBAL VARIABLES +******************************************************************************* +*/ +static int wp_card_no = 0; +WAN_LIST_HEAD(, wan_tdmv_) wan_tdmv_head = + WAN_LIST_HEAD_INITIALIZER(&wan_tdmv_head); +/* +******************************************************************************* +** FUNCTION PROTOTYPES +******************************************************************************* +*/ + +static int wp_tdmv_check_mtu(void* pcard, unsigned long timeslot_map, int *mtu); +static int wp_tdmv_create(void* pcard, wan_tdmv_conf_t*); +static int wp_tdmv_remove(void* pcard); +static int wp_tdmv_reg(void* pcard, wan_tdmv_if_conf_t*, unsigned int, unsigned char,netdevice_t*); +static int wp_tdmv_unreg(void* pcard, unsigned long ts_map); +static int wp_tdmv_software_init(wan_tdmv_t *wan_tdmv); +static int wp_tdmv_startup(struct zt_span *span); +static int wp_tdmv_shutdown(struct zt_span *span); +static int wp_tdmv_maint(struct zt_span *span, int cmd); +static int wp_tdmv_chanconfig(struct zt_chan *chan, int sigtype); +static int wp_tdmv_spanconfig(struct zt_span *span, struct zt_lineconfig *lc); +static int wp_tdmv_open(struct zt_chan *chan); +static int wp_tdmv_close(struct zt_chan *chan); +static void wp_tdmv_release(wp_tdmv_softc_t *wp); + +#if defined(__FreeBSD__) || defined(__OpenBSD__) +static int wp_tdmv_ioctl(struct zt_chan*, unsigned int, caddr_t); +#else +static int wp_tdmv_ioctl(struct zt_chan*, unsigned int, unsigned long); +#endif + +static int wp_tdmv_hwec(struct zt_chan *chan, int enable); +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) +static void wp_tdmv_tx_hdlc_hard(struct zt_chan *chan); +#endif + +static int wp_tdmv_state(void* pcard, int state); +static int wp_tdmv_running(void* pcard); + +/* RBS functions */ +static int wp_tdmv_sigctrl(sdla_t* card, wp_tdmv_softc_t *wp, int channel, int status); +static int wp_tdmv_rbsbits(struct zt_chan *chan, int bits); +static int wp_tdmv_tx_rbsbits(wp_tdmv_softc_t *wp); +static int wp_tdmv_is_rbsbits(wan_tdmv_t *wan_tdmv); +static int wp_tdmv_rbsbits_poll(wan_tdmv_t *wan_tdmv, void *card1); +static void wp_tdmv_report_rbsbits(void* pcard, int channel, unsigned char status); + +static void wp_tdmv_report_alarms(void* pcard, unsigned long te_alarm); + +/* Rx/Tx functions */ +static int wp_tdmv_rx_tx(void* pcard, netskb_t* skb); +static int wp_tdmv_rx_tx_span(void *pcard); +static int wp_tdmv_span_buf_rotate(void *pcard, u32, unsigned long); +static int wp_tdmv_ec_span(void *pcard); +static int wp_tdmv_rx_chan(wan_tdmv_t*, int, unsigned char*, unsigned char*); +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(ZT_DCHAN_TX) +static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len); +#endif +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) +static int wp_tdmv_rx_dchan(wan_tdmv_t*, int, unsigned char*, unsigned int); +#endif +static int wp_tdmv_rxcopy(wan_tdmv_t *wan_tdmv, unsigned char* rxbuf, int max_len); +static int wp_tdmv_rxprep(wan_tdmv_t* wan_tdmv, unsigned char*, int); +static int wp_tdmv_txcopy(wan_tdmv_t* wan_tdmv, unsigned char*, int); +static int wp_tdmv_txprep(wan_tdmv_t* wan_tdmv, unsigned char*, int); + +static inline void start_alarm(wp_tdmv_softc_t* wp); +static inline void stop_alarm(wp_tdmv_softc_t* wp); + +static int wp_tdmv_init(void* pcard, wanif_conf_t *conf); + +/****************************************************************************** +** wp_tdmv_te1_init() - +** +** OK +*/ +int wp_tdmv_te1_init(wan_tdmv_iface_t *iface) +{ + WAN_ASSERT(iface == NULL); + + iface->check_mtu = wp_tdmv_check_mtu; + iface->create = wp_tdmv_create; + iface->remove = wp_tdmv_remove; + iface->reg = wp_tdmv_reg; + iface->unreg = wp_tdmv_unreg; + iface->software_init = wp_tdmv_software_init; + iface->state = wp_tdmv_state; + iface->running = wp_tdmv_running; + iface->rx_tx = wp_tdmv_rx_tx; + iface->rx_chan = wp_tdmv_rx_chan; +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) + iface->rx_dchan = wp_tdmv_rx_dchan; +#endif + iface->rx_tx_span = wp_tdmv_rx_tx_span; + iface->is_rbsbits = wp_tdmv_is_rbsbits; //???? + iface->rbsbits_poll = wp_tdmv_rbsbits_poll; //????? + iface->init = wp_tdmv_init; + iface->buf_rotate = wp_tdmv_span_buf_rotate; + iface->ec_span = wp_tdmv_ec_span; + + return 0; +} + +static int wp_tdmv_check_mtu(void* pcard, unsigned long timeslot_map, int *mtu) +{ + sdla_t *card = (sdla_t*)pcard; + int x, num_of_channels = 0, max_channels; + + max_channels = GET_TE_CHANNEL_RANGE(&card->fe); + for (x = 0; x < max_channels; x++) { + if (wan_test_bit(x,×lot_map)){ + num_of_channels++; + } + } + *mtu = ZT_CHUNKSIZE * num_of_channels; + return 0; +} + +/****************************************************************************** +** wp_tdmv_create() - +** +** OK +*/ +static int wp_tdmv_create(void* pcard, wan_tdmv_conf_t *tdmv_conf) +{ + sdla_t *card = (sdla_t*)pcard; + wp_tdmv_softc_t *wp = NULL; + wan_tdmv_t *tmp = NULL; + + WAN_ASSERT(card == NULL); + WAN_ASSERT(tdmv_conf->span_no == 0); + memset(&card->wan_tdmv, 0x0, sizeof(wan_tdmv_t)); + /* We are forcing to register wanpipe devices at the same sequence + * that it defines in /etc/zaptel.conf */ + WAN_LIST_FOREACH(tmp, &wan_tdmv_head, next){ + if (tmp->spanno == tdmv_conf->span_no){ + DEBUG_EVENT("%s: Registering device with an incorrect span number!\n", + card->devname); + DEBUG_EVENT("%s: Another wanpipe device already configured to span #%d!\n", + card->devname, tdmv_conf->span_no); + return -EINVAL; + } + if (!WAN_LIST_NEXT(tmp, next)){ + break; + } + } + + card->wan_tdmv.max_timeslots = GET_TE_CHANNEL_RANGE(&card->fe); + card->wan_tdmv.spanno = tdmv_conf->span_no; + card->wandev.te_report_rbsbits = wp_tdmv_report_rbsbits; + card->wandev.te_report_alarms = wp_tdmv_report_alarms; + + wp = wan_kmalloc(sizeof(wp_tdmv_softc_t)); + if (wp == NULL){ + return -ENOMEM; + } + memset(wp, 0x0, sizeof(wp_tdmv_softc_t)); + card->wan_tdmv.sc = wp; + wp->spanno = tdmv_conf->span_no-1; + wp->num = wp_card_no++; + wp->card = card; + wp->devname = card->devname; + wp->lcode = WAN_FE_LCODE(&card->fe); + wp->frame = WAN_FE_FRAME(&card->fe); + wp->lbo = WAN_TE1_LBO(&card->fe); + wp->ise1 = IS_E1_FEMEDIA(&card->fe) ? 1 : 0; + wp->max_timeslots = IS_E1_FEMEDIA(&card->fe) ? 31: 24; + wp->max_rxtx_len = 0; + wan_spin_lock_init(&wp->lock); + wan_spin_lock_init(&wp->tx_rx_lock); + /* AHDLC */ + if (tdmv_conf->dchan){ + /* PRI signalling is selected with hw HDLC (dchan is not 0) */ + wp->dchan_map = tdmv_conf->dchan; + if (wp->ise1) { + wan_clear_bit(0,&wp->dchan_map); + } + } + + if (tmp){ + WAN_LIST_INSERT_AFTER(tmp, &card->wan_tdmv, next); + }else{ + WAN_LIST_INSERT_HEAD(&wan_tdmv_head, &card->wan_tdmv, next); + } + + return 0; +} + +/****************************************************************************** +** wp_tdmv_reg() - +** +** Returns: 0-31 - Return TDM Voice channel number. +** -EINVAL - otherwise +** OK +*/ +static int wp_tdmv_reg( void *pcard, + wan_tdmv_if_conf_t *tdmv_conf, + unsigned int active_ch, + u8 ec_enable, + netdevice_t *dev) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t *wp = NULL; + int i, channo = 0, cnt = 0; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wp = wan_tdmv->sc; + + if (wan_test_bit(WP_TDMV_REGISTER, &wp->flags)){ + DEBUG_EVENT("%s: Error: Master device has already been configured!\n", + card->devname); + return -EINVAL; + } + + /* + * T1: 1-24 + * E1: 0-31 */ + for(i = 0; imax_timeslots; i++){ + if (wan_test_bit(i, &active_ch)){ + wan_set_bit(i, &wp->timeslot_map); + if (tdmv_conf->tdmv_echo_off){ + wan_set_bit(i, &wp->echo_off_map); + } + channo = i; + cnt++; + } + } + + if (!cnt){ + DEBUG_EVENT("%s: Error: TDMV iface %s configured with 0 timeslots!\n", + card->devname, wan_netif_name(dev)); + return -EINVAL; + } + + if (cnt > 1){ + /* Unchannelized implementation */ + DEBUG_EVENT("%s: TDMV Mode :Unchannelized!\n", + wp->devname); + channo = 0; +#if 0 + if (is_last != WAN_TRUE){ + DEBUG_EVENT("%s: Error: Unchannelized interface must be the Master If (slots=%i)!\n", + wp->devname,cnt); + return -EINVAL; + } +#endif + if (tdmv_conf->tdmv_echo_off){ + DEBUG_EVENT("%s: TDMV Echo Ctrl:Off\n", + wp->devname); + } + wp->channelized = WAN_FALSE; + + if (wp->dchan_map){ + if (dev == NULL){ + DEBUG_EVENT("%s: ERROR: Device pointer is NULL for D-chan!\n", + wp->devname); + return -EINVAL; + } + wp->dchan_dev = dev; + } + }else{ + + /* Channelized implementation */ + if (wan_test_bit(channo, &wp->dchan_map)){ + if (dev == NULL){ + DEBUG_EVENT("%s: ERROR: Device pointer is NULL for D-chan!\n", + wp->devname); + return -EINVAL; + } + wp->dchan_dev = dev; + } + + if (tdmv_conf->tdmv_echo_off){ + DEBUG_EVENT("%s: TDMV Echo Ctrl:Off\n", + wp->devname); + } + memset(wp->chans[channo].sreadchunk, WAN_TDMV_IDLE_FLAG, ZT_CHUNKSIZE); + memset(wp->chans[channo].swritechunk, WAN_TDMV_IDLE_FLAG, ZT_CHUNKSIZE); + wp->chans[channo].readchunk = wp->chans[channo].sreadchunk; + wp->chans[channo].writechunk = wp->chans[channo].swritechunk; + wp->channelized = WAN_TRUE; + } + wp->hwec = ec_enable; + wp_tdmv_check_mtu(card, active_ch, &wp->max_rxtx_len); + return channo; +} + + +/****************************************************************************** +** wp_tdmv_del() - +** +** OK +*/ +static int wp_tdmv_unreg(void* pcard, unsigned long ts_map) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t *wp = NULL; + int channo = 0; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wp = wan_tdmv->sc; + + + for(channo = 0; channo < wp->max_timeslots; channo++){ + if (wan_test_bit(channo, &wp->timeslot_map)){ + wan_clear_bit(channo, &wp->timeslot_map); + wan_clear_bit(channo, &wp->echo_off_map); + memset(wp->chans[channo].sreadchunk, + WAN_TDMV_IDLE_FLAG, + ZT_CHUNKSIZE); + memset(wp->chans[channo].swritechunk, + WAN_TDMV_IDLE_FLAG, + ZT_CHUNKSIZE); + wp->chans[channo].readchunk = + wp->chans[channo].sreadchunk; + wp->chans[channo].writechunk = + wp->chans[channo].swritechunk; + } + } + return 0; +} + + +/****************************************************************************** +** wp_tdmv_running() - +** +** OK +*/ +static int wp_tdmv_running(void* pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t *wp = NULL; + + wp = wan_tdmv->sc; + if (wp && wp->usecount){ + DEBUG_EVENT("%s: WARNING: Wanpipe is still used by Asterisk!\n", + card->devname); + return -EINVAL; + } + return 0; +} + +/****************************************************************************** +** wp_tdmv_remove() - +** +** OK +*/ +static int wp_tdmv_remove(void* pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t *wp = NULL; + wan_smp_flag_t flags; + + if (!card->wan_tdmv.sc){ + return 0; + } + + wp = wan_tdmv->sc; + DEBUG_TDMV("Removing TDM VOICE interfaces\n"); + /* Release span, possibly delayed */ + if (wp && wp->timeslot_map){ + DEBUG_EVENT("%s: Some interfaces are not unregistered (%08lX)!\n", + card->devname, wp->timeslot_map); + return -EINVAL; + } + if (wp && wp->usecount){ + DEBUG_EVENT("%s: ERROR: Wanpipe is still used by Asterisk!\n", + card->devname); + return -EINVAL; + } + + wan_spin_lock_irq(&wp->lock, &flags); + card->wandev.te_report_rbsbits = NULL; + card->wandev.te_report_alarms = NULL; + wan_spin_unlock_irq(&wp->lock, &flags); + + if (wp){ + wan_clear_bit(WP_TDMV_RUNNING, &wp->flags); + wan_clear_bit(WP_TDMV_UP, &wp->flags); + wan_tdmv->sc = NULL; + wp_tdmv_sigctrl(card, wp, 0, WP_TDMV_DISABLE); + WAN_LIST_REMOVE(wan_tdmv, next); + wp_tdmv_release(wp); + }else{ + wan_tdmv->sc = NULL; + } + return 0; +} + +static int wp_tdmv_state(void* pcard, int state) +{ + sdla_t* card = (sdla_t*)pcard; + wan_tdmv_t* wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t* wp = NULL; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wp = (wp_tdmv_softc_t*)wan_tdmv->sc; + + switch(state){ + case WAN_CONNECTED: + wan_set_bit(WP_TDMV_UP, &wp->flags); + break; + + case WAN_DISCONNECTED: + wan_clear_bit(WP_TDMV_UP, &wp->flags); + wp->rbs_rx_pending = wp->sig_timeslot_map; + break; + } + return 0; +} + +static int wp_tdmv_sigctrl(sdla_t* card, wp_tdmv_softc_t *wp, int channel, int status) +{ + + WAN_ASSERT(wp == NULL); + WAN_ASSERT(card == NULL); + + if (status == WP_TDMV_ENABLE && IS_TDMV_RBS_READY(wp)){ + return 0; + }else if (status == WP_TDMV_DISABLE && !IS_TDMV_RBS_READY(wp)){ + return 0; + } + DEBUG_TDMV("%s: %s signalling mode for all channels!\n", + wp->devname, + (status==WP_TDMV_ENABLE)?"Enable":"Disable"); + + if (card->wandev.fe_iface.set_fe_sigctrl){ + if (wan_test_bit(WP_TDMV_SIG_POLL, &wp->flags)){ + card->wandev.fe_iface.set_fe_sigctrl( + &card->fe, + WAN_TE_SIG_POLL, + ENABLE_ALL_CHANNELS, + (status == WP_TDMV_ENABLE)?WAN_ENABLE:WAN_DISABLE); + }else{ + card->wandev.fe_iface.set_fe_sigctrl( + &card->fe, + WAN_TE_SIG_INTR, + ENABLE_ALL_CHANNELS, + (status == WP_TDMV_ENABLE)?WAN_ENABLE:WAN_DISABLE); + } + } + switch(status){ + case WP_TDMV_ENABLE: + wan_set_bit(WP_TDMV_SIG_ENABLE, &wp->flags); + wan_set_bit(WP_TDMV_RBS_READY, &wp->flags); + break; + case WP_TDMV_DISABLE: + wan_clear_bit(WP_TDMV_RBS_READY, &wp->flags); + wan_clear_bit(WP_TDMV_SIG_ENABLE, &wp->flags); + break; + default: + DEBUG_EVENT("%s: Unknown signalling mode (%d)\n", + wp->devname, status); + return -EINVAL; + } + return 0; +} + +/****************************************************************************** +** wp_tdmv_report_rbsbits() - Report A,B bit status changes to TDM Voice +** requests. +** +** DONE +*/ +static void wp_tdmv_report_rbsbits(void* pcard, int channel, unsigned char status) +{ + sdla_t* card = (sdla_t*)pcard; + wan_tdmv_t* wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t* wp = NULL; + int rxs = 0, i = 0; + + WAN_ASSERT1(wan_tdmv->sc == NULL); + wp = (wp_tdmv_softc_t*)wan_tdmv->sc; + + if (!wan_test_bit(channel-1, &wp->timeslot_map)){ + return; + } + + if (status & WAN_RBS_SIG_A) rxs |= ZT_ABIT; + if (status & WAN_RBS_SIG_B) rxs |= ZT_BBIT; + if (status & WAN_RBS_SIG_C) rxs |= ZT_CBIT; + if (status & WAN_RBS_SIG_D) rxs |= ZT_DBIT; +#if 0 + if (wp->ise1){ + FIXME_MSG("wp_tdmv_report_rbsbits"); + /* Read 5 registers at a time, loading 10 channels at a time */ + for (i = (x *5); i < (x * 5) + 5; i++) { + /* FIXME a = __t1_get_reg(wp, 0x31 + i); */ + /* Get high channel in low bits */ + rxs = (a & 0xf); + if (!(wp->chans[i+15].sig & ZT_SIG_CLEAR)) { + if (wp->chans[i+15].rxsig != rxs) + zt_rbsbits(&wp->chans[i+15], rxs); + } + rxs = (a >> 4) & 0xf; + if (!(wp->chans[i].sig & ZT_SIG_CLEAR)) { + if (wp->chans[i].rxsig != rxs) + zt_rbsbits(&wp->chans[i], rxs); + } + } + } +#endif + for(i=0; i < wp->span.channels;i++){ + if (wp->chans[i].chanpos == channel) + break; + } + if (i == wp->span.channels){ + return; + } + if (!(wp->chans[i].sig & ZT_SIG_CLEAR) && + (wp->chans[i].rxsig != rxs)){ + zt_rbsbits(&wp->chans[i], rxs); + DEBUG_TDMV( + "[TDMV] %s: %s:%02d(%d) RX RBS: A:%1d B:%1d C:%1d D:%1d\n", + wp->devname, + (wp->ise1) ? "E1" : "T1", + channel, wp->chans[i].channo, + (rxs & ZT_ABIT) ? 1 : 0, + (rxs & ZT_BBIT) ? 1 : 0, + (rxs & ZT_CBIT) ? 1 : 0, + (rxs & ZT_DBIT) ? 1 : 0); + } +} + +/****************************************************************************** +** wp_tdmv_report_alarms() - +** +** DONE +*/ +static void wp_tdmv_report_alarms(void* pcard, unsigned long te_alarm) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t *wp = NULL; + int alarms = 0, prev_alarms; + int x,j; + + /* The sc pointer can be NULL, on shutdown. In this + * case don't generate error, just get out */ + wp = wan_tdmv->sc; + if (!wp){ + return; + } + + /* And consider only carrier alarms */ + wp->span.alarms &= (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_NOTOPEN); + prev_alarms = wp->span.alarms; + + if (wp->ise1){ + /* XXX Implement me XXX */ + }else{ + /* Detect loopup code if we're not sending one */ + if (!wp->span.mainttimer && (te_alarm & WAN_TE_BIT_LOOPUP_CODE)){ + /* Loop-up code detected */ + if ((wp->loopupcnt++ > 80) && (wp->span.maintstat != ZT_MAINT_REMOTELOOP)){ + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_DDLB_MODE, + WAN_TE1_DEACTIVATE_LB); + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_LINELB_MODE, + WAN_TE1_ACTIVATE_LB); + wp->span.maintstat = ZT_MAINT_REMOTELOOP; + } + }else{ + wp->loopupcnt = 0; + } + /* Same for loopdown code */ + if (!wp->span.mainttimer && (te_alarm & WAN_TE_BIT_LOOPDOWN_CODE)){ + /* Loop-down code detected */ + if ((wp->loopdowncnt++ > 80) && (wp->span.maintstat == ZT_MAINT_REMOTELOOP)){ + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_DDLB_MODE, + WAN_TE1_DEACTIVATE_LB); + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_LINELB_MODE, + WAN_TE1_DEACTIVATE_LB); + wp->span.maintstat = ZT_MAINT_NONE; + } + }else{ + wp->loopdowncnt = 0; + } + } + + if (wp->span.lineconfig & ZT_CONFIG_NOTOPEN) { + for (x=0,j=0;x < wp->span.channels;x++){ + if ((wp->chans[x].flags & ZT_FLAG_OPEN) || + (wp->chans[x].flags & ZT_FLAG_NETDEV)){ + j++; + } + } + if (!j){ + alarms |= ZT_ALARM_NOTOPEN; + } + } + + /* Note: The alarm checking should match + Alarm checking in sdla_te1.c and + sdla_8te1.c + */ + + if (wp->ise1) { + if (te_alarm & WAN_TE_BIT_RED_ALARM) + alarms |= ZT_ALARM_RED; + if (te_alarm & WAN_TE_BIT_OOF_ALARM) + alarms |= ZT_ALARM_RED; + } else { + /* Check actual alarm status */ + if (te_alarm & WAN_TE_BIT_RED_ALARM) + alarms |= ZT_ALARM_RED; + if (te_alarm & WAN_TE_BIT_OOF_ALARM) + alarms |= ZT_ALARM_RED; + } + /* Keep track of recovering */ + if ((!alarms) && wp->span.alarms) + wp->alarmtimer = ZT_ALARMSETTLE_TIME; + +#if 0 + /* If receiving alarms, go into Yellow alarm state */ + if (alarms && (!wp->span.alarms)) { + DEBUG_TDMV("%s: Going into yellow alarm\n", + wp->devname); + if (card->wandev.fe_iface.set_fe_alarm){ + card->wandev.fe_iface.set_fe_alarm(&card->fe, WAN_TE_BIT_YEL_ALARM); + } + } +#endif + + if (wp->span.alarms != alarms) { + /* FIXME: Alarm status changed!!! */ + DEBUG_TDMV("%s: Alarm status changed %X!\n", + wp->devname,alarms); + } + /* + ** if (wp->alarmtimer) + ** alarms |= ZT_ALARM_RECOVER; */ + if (te_alarm & WAN_TE_BIT_YEL_ALARM) + alarms |= ZT_ALARM_YELLOW; + + wp->span.alarms = alarms; + zt_alarm_notify(&wp->span); + + return; +} + +/****************************************************************************** +** wp_tdmv_txcopy() - +** +** OK +*/ +static int +wp_tdmv_txcopy(wan_tdmv_t *wan_tdmv, unsigned char* txbuf, int max_len) +{ + wp_tdmv_softc_t *wp = wan_tdmv->sc; + int x = 0, y = 0, offset = 0; + + WAN_ASSERT(wp == NULL); + for (y=0;yspan.channels;x++){ + if (!wan_test_bit(x,&wp->timeslot_map)){ + continue; + } + txbuf[offset++] = wp->chans[x].writechunk[y]; + } + } + return (offset+1); +} + +/****************************************************************************** +** wp_tdmv_txprep() - +** +** OK +*/ +static int +wp_tdmv_txprep(wan_tdmv_t *wan_tdmv, unsigned char* txbuf, int max_len) +{ + wp_tdmv_softc_t *wp = wan_tdmv->sc; + + WAN_ASSERT2(wp == NULL, 0); + zt_transmit(&wp->span); + return wp_tdmv_txcopy(wan_tdmv, txbuf, max_len); +} + +/****************************************************************************** +** wp_tdmv_rxcopy() - +** +** OK +*/ +static int +wp_tdmv_rxcopy(wan_tdmv_t *wan_tdmv, unsigned char* rxbuf, int max_len) +{ + wp_tdmv_softc_t *wp = wan_tdmv->sc; + int x, y, offset = 0; + int channels = wp->span.channels; + unsigned char value; + + WAN_ASSERT(wp == NULL); + for (y=0;ytimeslot_map)){ + value = rxbuf[offset++]; + }else{ + value = WAN_TDMV_IDLE_FLAG; /* 0xFE; */ + } + wp->chans[x].readchunk[y] = value; + } + } + return offset; +} + +/****************************************************************************** +** wp_tdmv_rxprep() - +** +** OK +*/ +static int +wp_tdmv_rxprep(wan_tdmv_t *wan_tdmv, unsigned char* rxbuf, int max_len) +{ + wp_tdmv_softc_t *wp = wan_tdmv->sc; + int x, offset = 0, channels = wp->span.channels; + + WAN_ASSERT2(wp == NULL, 0); + + offset = wp_tdmv_rxcopy(wan_tdmv, rxbuf, max_len); + + if (!wp->echo_off_map){ + for (x = 0; x < channels; x++){ +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + wan_tdmv_rxtx_pwr_t *pwr_rxtx = &wan_tdmv->chan_pwr[x]; + wp_tdmv_echo_check(wan_tdmv, &wp->chans[0], x); + if(pwr_rxtx->current_state != ECHO_ABSENT){ +#endif + zt_ec_chunk( + &wp->chans[x], + wp->chans[x].readchunk, + wp->chans[x].writechunk); +#if 0 + zt_ec_chunk( + &wp->chans[x], + wp->chans[x].readchunk, + wp->ec_chunk1[x]); + memcpy( + wp->ec_chunk1[x], + wp->chans[x].writechunk, + ZT_CHUNKSIZE); +#endif + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + }/* if() */ +#endif + }/* for() */ + }/* if() */ + + zt_receive(&wp->span); + return (offset); +} + + +/****************************************************************************** +** wp_tdmv_rx_tx() - +** +** OK +*/ +static int wp_tdmv_rx_tx(void* pcard, netskb_t* skb) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t *wp = NULL; + int len; + + WAN_ASSERT(wan_tdmv->sc == NULL); + WAN_ASSERT(skb == NULL); + wp = wan_tdmv->sc; + + if (wan_skb_len(skb) != wp->max_rxtx_len){ + if (WAN_NET_RATELIMIT()) { + DEBUG_EVENT("%s: Internal Error[%s:%d]: Wrong buffer lenght %d (%d)!\n", + wp->devname, + __FUNCTION__,__LINE__, + wan_skb_len(skb), + wp->max_rxtx_len); + } + return 0; + } + + wp->intcount ++; + + len = wp_tdmv_rxprep( + wan_tdmv, + wan_skb_data(skb), + wan_skb_len(skb)); + len = wp_tdmv_txprep( + wan_tdmv, + wan_skb_data(skb), + wan_skb_len(skb)); + + if (wan_test_bit(WP_TDMV_RBS_UPDATE, &wp->flags)){ + if (card->wandev.fe_iface.report_rbsbits){ + card->wandev.fe_iface.report_rbsbits(&card->fe); + } + wan_clear_bit(WP_TDMV_RBS_UPDATE, &wp->flags); + wan_clear_bit(WP_TDMV_RBS_BUSY, &wp->flags); + } + + return wp->max_rxtx_len; +} + + +/* +** STATIC FUNCTION DEFINITIONS +** +*/ + +/****************************************************************************** +** wp_tdmv_software_init() - +** +** OK +*/ +static int wp_tdmv_software_init(wan_tdmv_t *wan_tdmv) +{ + sdla_t *card = NULL; + wp_tdmv_softc_t *wp = wan_tdmv->sc; + int x = 0; + + WAN_ASSERT(wp == NULL); + WAN_ASSERT(wp->card == NULL); + card = wp->card; + + if (wan_test_bit(WP_TDMV_REGISTER, &wp->flags)){ + DEBUG_EVENT("%s: Wanpipe device is already registered to Zaptel span # %d!\n", + wp->devname, wp->span.spanno); + return 0; + } +#if 0 + if (wp->ise1 && wp->channelized == WAN_FALSE){ + /* Timeslot map for E1 includes ts0. TDM voice does never + ** use ts0, so i will shift map 1 bit right to get + ** everything alignment as T1 */ + wp->timeslot_map = wp->timeslot_map >> 1; + wp->echo_off_map = wp->echo_off_map >> 1; + } +#endif + if (wp->ise1){ + sprintf(wp->span.name, "WPE1/%d", wp->num); + }else{ + sprintf(wp->span.name, "WPT1/%d", wp->num); + } + sprintf(wp->span.desc, "%s card %d", wp->devname, wp->num); + wp->span.spanconfig = wp_tdmv_spanconfig; + wp->span.chanconfig = wp_tdmv_chanconfig; + wp->span.startup = wp_tdmv_startup; + wp->span.shutdown = wp_tdmv_shutdown; + wp->span.rbsbits = wp_tdmv_rbsbits; + wp->span.maint = wp_tdmv_maint; + wp->span.open = wp_tdmv_open; + wp->span.close = wp_tdmv_close; + wp->span.channels = wp->max_timeslots; + wp->span.chans = wp->chans; + wp->span.flags = ZT_FLAG_RBS; + wp->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF; + wp->span.ioctl = wp_tdmv_ioctl; + /* Set this pointer only if card has hw echo canceller module */ + if (wp->hwec == WANOPT_YES && card->wandev.ec_dev){ + /* Initialize it only if HWEC option is enabled */ + wp->span.echocan = wp_tdmv_hwec; + } +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) + if (wp->dchan_map){ + DEBUG_EVENT("%s: Enable Zaptel HW DCHAN interface\n", + wp->devname); + wp->span.hdlc_hard_xmit = wp_tdmv_tx_hdlc_hard; + } +#endif + wp->span.pvt = wp; + if (wp->ise1){ + wp->span.deflaw = ZT_LAW_ALAW; + card->fe.fe_cfg.tdmv_law = WAN_TDMV_ALAW; + wp->span.linecompat = ZT_CONFIG_HDB3 | ZT_CONFIG_CCS | ZT_CONFIG_CRC4; + }else{ + wp->span.deflaw = ZT_LAW_MULAW; + card->fe.fe_cfg.tdmv_law = WAN_TDMV_MULAW; + wp->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF; + } +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) + init_waitqueue_head(&wp->span.maintq); +#endif + for (x=0;xspan.channels;x++) { + sprintf(wp->chans[x].name, "%s/%d", wp->span.name, x+1); + if (wan_test_bit(x,&wp->timeslot_map)){ + DEBUG_TEST("%s: Configure channel %d for voice (%s)!\n", + wp->devname, + x + 1, + wp->chans[x].name); + wp->chans[x].sigcap = + ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_EM_E1 | + ZT_SIG_FXSLS | ZT_SIG_FXSGS | + ZT_SIG_FXSKS | ZT_SIG_FXOLS | + ZT_SIG_FXOGS | ZT_SIG_FXOKS | + ZT_SIG_CAS | ZT_SIG_DACS_RBS +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) + | ZT_SIG_HARDHDLC +#endif + ; + }else{ + wp->chans[x].sigcap = ZT_SIG_NONE; + } + wp->chans[x].pvt = wp; + wp->chans[x].chanpos = x + 1; + wp->chans[x].rxsig = 0x00; + } + + if (zt_register(&wp->span, 0)) { + DEBUG_EVENT("%s: Unable to register span with zaptel\n", + wp->devname); + return -EINVAL; + } + + if (wp->span.spanno != wp->spanno +1){ + DEBUG_EVENT("\n"); + DEBUG_EVENT("WARNING: Span number %d is already used by another device!\n", + wp->spanno + 1); + DEBUG_EVENT(" Possible cause: Another TDM driver already loaded!\n"); + DEBUG_EVENT(" Solution: Unload wanpipe and check currently\n"); + DEBUG_EVENT(" used spans in /proc/zaptel directory.\n"); + DEBUG_EVENT(" Reconfiguring device %s to new span number # %d\n", + wp->devname,wp->span.spanno); + DEBUG_EVENT("\n"); + wp->spanno = wp->span.spanno-1; + }else{ + DEBUG_EVENT("%s: Wanpipe device is registered to Zaptel span # %d!\n", + wp->devname, wp->span.spanno); + } + if (wp->channelized == WAN_FALSE && wp->dchan_map){ + /* Apr 15, 2005 + * For unchannelized mode, if HW HDLC protocol is selected + * by using dchan configuration option, remove dchan timeslot + * from timeslot and echo map. */ + if (wp->ise1) { + wp->dchan_map=wp->dchan_map>>1; + wan_clear_bit(0,&wp->dchan_map); + } + + wp->timeslot_map &= ~wp->dchan_map; + wp->echo_off_map &= ~wp->dchan_map; + } + + wp_tdmv_check_mtu(card, wp->timeslot_map, &wp->max_rxtx_len); + wan_set_bit(WP_TDMV_REGISTER, &wp->flags); + if (!wan_tdmv->sig_intr_enable){ + wan_set_bit(WP_TDMV_SIG_POLL, &wp->flags); + /* These function is available if poll used for signalling detection */ + card->tdmv_iface.is_rbsbits = wp_tdmv_is_rbsbits; + card->tdmv_iface.rbsbits_poll = wp_tdmv_rbsbits_poll; + } + return 0; +} + + +/****************************************************************************** +** wp_tdmv_startup() - +** +** OK +*/ +static int wp_tdmv_startup(struct zt_span *span) +{ + wp_tdmv_softc_t* wp = NULL; + int i; + + WAN_ASSERT2(span == NULL, -ENODEV); + WAN_ASSERT2(span->pvt == NULL, -ENODEV); + wp = span->pvt; + + /* initialize the start value for the entire chunk of last ec buffer */ + for(i = 0; i < span->channels; i++){ + memset(wp->ec_chunk1[i], + ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE); + memset(wp->ec_chunk2[i], + ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE); + } + + + if (!(span->flags & ZT_FLAG_RUNNING)) { + /* Only if we're not already going */ + span->flags |= ZT_FLAG_RUNNING; + } + wan_set_bit(WP_TDMV_RUNNING, &wp->flags); + return 0; +} + +/****************************************************************************** +** wp_tdmv_shutdown() - +** +** OK +*/ +static int wp_tdmv_shutdown(struct zt_span *span) +{ + wp_tdmv_softc_t* wp = NULL; + wan_smp_flag_t flags; + + WAN_ASSERT2(span == NULL, -ENODEV); + WAN_ASSERT2(span->pvt == NULL, -ENODEV); + wp = span->pvt; + wan_clear_bit(WP_TDMV_RUNNING, &wp->flags); + wan_spin_lock_irq(&wp->lock, &flags); + span->flags &= ~ZT_FLAG_RUNNING; + wan_spin_unlock_irq(&wp->lock, &flags); + return 0; +} + +/****************************************************************************** +** wp_tdmv_maint() - +** +** OK +*/ +static int wp_tdmv_maint(struct zt_span *span, int cmd) +{ + wp_tdmv_softc_t *wp = span->pvt; + sdla_t *card = wp->card; + int res = 0; + wan_smp_flag_t flags; + + WAN_ASSERT2(span == NULL, -ENODEV); + WAN_ASSERT2(span->pvt == NULL, -ENODEV); + wp = span->pvt; + wan_spin_lock_irq(&wp->lock, &flags); + if (wp->ise1) { +#if 0 + /* FIXME: Support E1 */ + switch(cmd) { + case ZT_MAINT_NONE: + DEBUG_EVENT("%s: E1: Set to normal mode (no local/remote loops)\n", + wp->card->devname); + /* FIXME __t1_set_reg(wp,0xa8,0); */ /* no loops */ + break; + case ZT_MAINT_LOCALLOOP: + DEBUG_EVENT("%s: E1: Set to local loopback mode\n", + wp->card->devname); + /* FIXME __t1_set_reg(wp,0xa8,0x40); */ /* local loop */ + break; + case ZT_MAINT_REMOTELOOP: + DEBUG_EVENT("%s: E1: Set to remote loopback mode\n", + wp->card->devname); + /* FIXME __t1_set_reg(wp,0xa8,0x80);*/ /* remote loop */ + break; + case ZT_MAINT_LOOPUP: + case ZT_MAINT_LOOPDOWN: + case ZT_MAINT_LOOPSTOP: + res = -ENOSYS; + break; + default: + DEBUG_EVENT("%s: E1: Unknown maintenance mode (%d)\n", + wp->card->devname, cmd); + res = -EINVAL; + break; + } +#endif + }else{ + switch(cmd) { + case ZT_MAINT_NONE: + DEBUG_EVENT("%s: T1: Set to normal mode (no local/remote loop)\n", + wp->card->devname); + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_DDLB_MODE, + WAN_TE1_DEACTIVATE_LB); + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_LINELB_MODE, + WAN_TE1_DEACTIVATE_LB); + break; + case ZT_MAINT_LOCALLOOP: + DEBUG_EVENT("%s: T1: Set to local loopback mode (local/no remote loop)\n", + wp->card->devname); + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_LINELB_MODE, + WAN_TE1_DEACTIVATE_LB); + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_DDLB_MODE, + WAN_TE1_ACTIVATE_LB); + break; + case ZT_MAINT_REMOTELOOP: + DEBUG_EVENT("%s: T1: Set to remote loopback mode (no local/remote loop)\n", + wp->card->devname); + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_LINELB_MODE, + WAN_TE1_ACTIVATE_LB); + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_LINELB_MODE, + WAN_TE1_DEACTIVATE_LB); + break; + case ZT_MAINT_LOOPUP: + DEBUG_EVENT("%s: T1: Send loopup code\n", + wp->card->devname); + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_TX_LB_MODE, + WAN_TE1_ACTIVATE_LB); + break; + case ZT_MAINT_LOOPDOWN: + DEBUG_EVENT("%s: T1: Send loopdown code\n", + wp->card->devname); + card->wandev.fe_iface.set_fe_lbmode( + &wp->card->fe, + WAN_TE1_TX_LB_MODE, + WAN_TE1_DEACTIVATE_LB); + break; + case ZT_MAINT_LOOPSTOP: + DEBUG_EVENT("%s: T1: Stop sending loop code\n", + wp->card->devname); + /* FIXME __t1_set_reg(wp,0x30,0); */ /* stop sending loopup code */ + break; + default: + DEBUG_EVENT("%s: T1: Unknown maintenance mode (%d)\n", + wp->card->devname, cmd); + res = -EINVAL; + } + } + wan_spin_unlock_irq(&wp->lock, &flags); + return res; +} + +static void wp_tdmv_set_clear(wp_tdmv_softc_t* wp) +{ + WAN_ASSERT1(wp == NULL); + + /* FIXME: Add action for this function */ +} + +/****************************************************************************** +** sigstr() - +** +** OK +*/ +#if 0 +static char *wp_tdmv_sigstr(int sig) +{ + switch (sig) { + case ZT_SIG_FXSLS: + return "FXSLS"; + case ZT_SIG_FXSKS: + return "FXSKS"; + case ZT_SIG_FXSGS: + return "FXSGS"; + case ZT_SIG_FXOLS: + return "FXOLS"; + case ZT_SIG_FXOKS: + return "FXOKS"; + case ZT_SIG_FXOGS: + return "FXOGS"; + case ZT_SIG_EM: + return "E&M"; + case ZT_SIG_CLEAR: + return "Clear"; + case ZT_SIG_HDLCRAW: + return "HDLCRAW"; + case ZT_SIG_HDLCFCS: + return "HDLCFCS"; + case ZT_SIG_HDLCNET: + return "HDLCNET"; + case ZT_SIG_SLAVE: + return "Slave"; + case ZT_SIG_CAS: + return "CAS"; + case ZT_SIG_DACS: + return "DACS"; + case ZT_SIG_SF: + return "SF (ToneOnly)"; + case ZT_SIG_NONE: + default: + return "Unconfigured"; + } + +} +#endif + +static int wp_tdmv_chanconfig(struct zt_chan *chan, int sigtype) +{ + sdla_t *card; + wp_tdmv_softc_t *wp = NULL; + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wp = chan->pvt; + card = (sdla_t*)wp->card; + + DEBUG_TDMV("%s: Configuring chan %d..\n", wp->devname, chan->chanpos); + if (chan->span->flags & ZT_FLAG_RUNNING){ + wp_tdmv_set_clear(wp); + } + + if (!wan_test_and_set_bit(chan->chanpos, &wp->config_tsmap)){ + wp->timeslots++; + } + if (!(sigtype & ZT_SIG_CLEAR)){ + /* Set Signalling channel map */ + if (!wan_test_and_set_bit(chan->chanpos-1, &wp->sig_timeslot_map)){ + wp->sig_timeslots ++; + wan_set_bit(chan->chanpos-1, &wp->rbs_rx_pending); + } + wp_tdmv_sigctrl(card, wp, chan->chanpos, WP_TDMV_ENABLE); + } + return 0; +} + +/****************************************************************************** +** wp_tdmv_spanconfig() - +** +** OK +*/ +static int wp_tdmv_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) +{ + wp_tdmv_softc_t *wp = NULL; + sdla_t *card = NULL; + int err = 0; + + WAN_ASSERT2(span == NULL, -ENODEV); + WAN_ASSERT2(span->pvt == NULL, -ENODEV); + wp = span->pvt; + card = (sdla_t*)wp->card; + DEBUG_TDMV("%s: Configuring span device..\n", wp->devname); + switch(wp->lcode){ + case WAN_LCODE_AMI: + span->lineconfig |= ZT_CONFIG_AMI; + break; + case WAN_LCODE_B8ZS: + span->lineconfig |= ZT_CONFIG_B8ZS; + break; + case WAN_LCODE_HDB3: + span->lineconfig |= ZT_CONFIG_HDB3; + break; + } + switch(wp->frame){ + case WAN_FR_ESF: + span->lineconfig |= ZT_CONFIG_ESF; + break; + case WAN_FR_D4: + span->lineconfig |= ZT_CONFIG_D4; + break; + case WAN_FR_CRC4: + span->lineconfig |= ZT_CONFIG_CRC4; + break; + } + if (wp->ise1){ + if (lc->lineconfig & ZT_CONFIG_CCS){ + span->lineconfig |= ZT_CONFIG_CCS; + card->fe.fe_cfg.cfg.te_cfg.sig_mode = WAN_TE1_SIG_CCS; + }else{ + card->fe.fe_cfg.cfg.te_cfg.sig_mode = WAN_TE1_SIG_CAS; + } + if (card->wandev.fe_iface.reconfig){ + card->wandev.fe_iface.reconfig(&card->fe); + } + } + span->txlevel = 0; + switch(wp->lbo){ + case WAN_T1_LBO_0_DB: + DEBUG_TE1("%s: LBO 0 dB\n", card->devname); + span->txlevel = 0; + break; + case WAN_T1_LBO_75_DB: + DEBUG_TE1("%s: LBO 7.5 dB\n", card->devname); + span->txlevel = 5; + break; + case WAN_T1_LBO_15_DB: + DEBUG_TE1("%s: LBO 15 dB\n", card->devname); + span->txlevel = 6; + break; + case WAN_T1_LBO_225_DB: + DEBUG_TE1("%s: LBO 22.5 dB\n", card->devname); + span->txlevel = 7; + break; + case WAN_T1_0_110: + DEBUG_TE1("%s: LBO 0-110 ft.\n", card->devname); + span->txlevel = 0; + break; + case WAN_T1_110_220: + DEBUG_TE1("%s: LBO 110-220 ft.\n", card->devname); + span->txlevel = 1; + break; + case WAN_T1_220_330: + DEBUG_TE1("%s: LBO 220-330 ft.\n", card->devname); + span->txlevel = 2; + break; + case WAN_T1_330_440: + DEBUG_TE1("%s: LBO 330-440 ft.\n", card->devname); + span->txlevel = 3; + break; + case WAN_T1_440_550: + DEBUG_TE1("%s: LBO 440-550 ft.\n", card->devname); + span->txlevel = 3; + break; + case WAN_T1_550_660: + DEBUG_TE1("%s: LBO 550-660 ft.\n", card->devname); + span->txlevel = 4; + break; + } + + span->rxlevel = 0; + /* Do we want to SYNC on receive or not */ + wp->sync = lc->sync; + /* */ + /* If already running, apply changes immediately */ + if (span->flags & ZT_FLAG_RUNNING){ + err = wp_tdmv_startup(span); + } + + return err; +} + + +/****************************************************************************** +** wp_tdmv_rbsbits() - Set A,B bits according TDM Voice requests. +** +** DONE +*/ +static int wp_tdmv_rbsbits(struct zt_chan *chan, int bits) +{ + wp_tdmv_softc_t *wp = NULL; + sdla_t *card = NULL; + unsigned char ABCD_bits = 0x00; + + /* Byte offset */ + WAN_ASSERT2(chan == NULL, 0); + if ((wp = chan->pvt) == NULL) return 0; + WAN_ASSERT2(wp->card == NULL, 0); + card = (sdla_t*)wp->card; + if (!wan_test_bit(chan->chanpos-1, &wp->timeslot_map)){ + return 0; + } + if (!wan_test_bit(WP_TDMV_SIG_ENABLE, &wp->flags)){ + return 0; + } + if (bits & ZT_ABIT) ABCD_bits |= WAN_RBS_SIG_A; + if (bits & ZT_BBIT) ABCD_bits |= WAN_RBS_SIG_B; + if (bits & ZT_CBIT) ABCD_bits |= WAN_RBS_SIG_C; + if (bits & ZT_DBIT) ABCD_bits |= WAN_RBS_SIG_D; + + if (IS_CHAN_HARDHDLC(chan)){ + return 0; + } + + DEBUG_TDMV( + "[TDMV] %s: %s:%02d(%d) TX RBS: A:%1d B:%1d C:%1d D:%1d\n", + wp->devname, + (wp->ise1) ? "E1" : "T1", + chan->chanpos, chan->channo, + (ABCD_bits & WAN_RBS_SIG_A) ? 1 : 0, + (ABCD_bits & WAN_RBS_SIG_B) ? 1 : 0, + (ABCD_bits & WAN_RBS_SIG_C) ? 1 : 0, + (ABCD_bits & WAN_RBS_SIG_D) ? 1 : 0); + + if (wan_test_and_set_bit(chan->chanpos-1, &wp->rbs_tx_status)){ + if (ABCD_bits == wp->rbs_tx[chan->chanpos-1]){ + return 0; + } + if (wan_test_and_set_bit(chan->chanpos-1, &wp->rbs_tx1_status)){ + if (ABCD_bits == wp->rbs_tx1[chan->chanpos-1]){ + return 0; + } + DEBUG_EVENT("%s: Critical Error: TX RBS for channel %d\n", + wp->devname, + chan->chanpos); + } + wp->rbs_tx1[chan->chanpos-1] = ABCD_bits; + }else{ + wp->rbs_tx[chan->chanpos-1] = ABCD_bits; + } +#if 0 + wan_set_bit(7, &ABCD_bits); + if (wan_test_and_set_bit(7, &wp->rbs_tx[chan->chanpos-1])){ + if (ABCD_bits == wp->rbs_tx[chan->chanpos-1]){ + return 0; + } + if (wan_test_and_set_bit(7, &wp->rbs_tx1[chan->chanpos-1])){ + if (ABCD_bits == wp->rbs_tx1[chan->chanpos-1]){ + return 0; + } + DEBUG_EVENT("%s: Critical Error: TX RBS for channel %d\n", + wp->devname, + chan->chanpos); + } + wp->rbs_tx1[chan->chanpos-1] = ABCD_bits; + }else{ + wp->rbs_tx[chan->chanpos-1] = ABCD_bits; + } +#endif + return 0; +} + + +/****************************************************************************** +** wp_tdmv_is_rbsbits() - +** +** Returns: 1 - start RBS poll routine, 0 - otherwise +*/ +static int wp_tdmv_is_rbsbits(wan_tdmv_t *wan_tdmv) +{ + wp_tdmv_softc_t *wp = NULL; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wp = wan_tdmv->sc; + + /* Do not read signalling bits if Asterisk not configured to */ + if (!IS_TDMV_SIG(wp)){ + return 0; + } + + if (wan_test_and_set_bit(WP_TDMV_RBS_BUSY, &wp->flags)){ + /* RBS read still in progress or not ready*/ + return 0; + } + + if (wp->rbs_tx_status || wp->rbs_tx1_status){ + return 1; + } + + if (!IS_TDMV_UP(wp)){ + wan_clear_bit(WP_TDMV_RBS_BUSY, &wp->flags); + return 0; + } + + /* Increment RX/TX interrupt counter */ + wp->rbscount++; + + /* RBS_POLL + ** Update RBS bits now (we don't have to do very often) */ + if (!(wp->rbscount & 0xF)){ + return 1; + } + + /* Wait for the next time */ + wan_clear_bit(WP_TDMV_RBS_BUSY, &wp->flags); + return 0; +} + +/****************************************************************************** +** wp_tdmv_rbsbits_poll() - +** +** DONE +*/ +static int wp_tdmv_rbsbits_poll(wan_tdmv_t *wan_tdmv, void *card1) +{ + sdla_t *card = (sdla_t*)card1; + wp_tdmv_softc_t *wp = NULL; + int i, x; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wp = wan_tdmv->sc; + + /* TX rbsbits */ + if (wp->rbs_tx_status || wp->rbs_tx1_status){ + wp_tdmv_tx_rbsbits(wp); + } + + if (!IS_TDMV_UP(wp)){ + wan_clear_bit(WP_TDMV_RBS_BUSY, &wp->flags); + return 0; + } + if (wp->rbs_rx_pending){ + DEBUG_TEST("%s: %s:%d: Reading RBS (pending)\n", + wp->devname, + __FUNCTION__,__LINE__); + for(i=0; i < wp->max_timeslots;i++){ + if (wan_test_bit(i, &wp->rbs_rx_pending)){ + wan_clear_bit(i, &wp->rbs_rx_pending); + card->wandev.fe_iface.read_rbsbits( + &card->fe, + i+1, + WAN_TE_RBS_UPDATE|WAN_TE_RBS_REPORT); + } + } + wan_set_bit(WP_TDMV_RBS_UPDATE, &wp->flags); + return 0; + } + + /* RX rbsbits */ + DEBUG_TEST("%s: %s:%d: Reading RBS (%s)\n", + wp->devname, + __FUNCTION__,__LINE__, + (wp->rbscount % 1000) ? "Normal" : "Sanity"); + if (wp->rbscount % 1000 == 0){ + for(x = 0; x < wp->max_timeslots; x++){ + if (wan_test_bit(x, &wp->sig_timeslot_map)){ + card->wandev.fe_iface.read_rbsbits( + &card->fe, + x+1, + WAN_TE_RBS_UPDATE); + } + } + }else{ + if (card->wandev.fe_iface.check_rbsbits == NULL){ + DEBUG_EVENT("%s: Internal Error [%s:%d]!\n", + wp->devname, + __FUNCTION__,__LINE__); + return -EINVAL; + } + card->wandev.fe_iface.check_rbsbits( + &card->fe, + 1, wp->sig_timeslot_map, 0); + card->wandev.fe_iface.check_rbsbits( + &card->fe, + 9, wp->sig_timeslot_map, 0); + card->wandev.fe_iface.check_rbsbits( + &card->fe, + 17, wp->sig_timeslot_map, 0); + if (wp->ise1){ + card->wandev.fe_iface.check_rbsbits( + &card->fe, + 25, wp->sig_timeslot_map, 0); + } + } + wan_set_bit(WP_TDMV_RBS_UPDATE, &wp->flags); + return 0; +} + +/****************************************************************************** +** wp_tdmv_tx_rbsbits() - +** +** DONE +*/ +static int wp_tdmv_tx_rbsbits(wp_tdmv_softc_t *wp) +{ + sdla_t *card; + int x; + + WAN_ASSERT2(wp->card == NULL, 0); + card = (sdla_t*)wp->card; + for(x=0;xmax_timeslots;x++){ + if (wan_test_bit(x, &wp->rbs_tx_status)){ + card->wandev.fe_iface.set_rbsbits( + &wp->card->fe, + x+1, + wp->rbs_tx[x]); + wan_clear_bit(x, &wp->rbs_tx_status); + if (wan_test_bit(x, &wp->rbs_tx1_status)){ + card->wandev.fe_iface.set_rbsbits( + &wp->card->fe, + x+1, + wp->rbs_tx1[x]); + wan_clear_bit(x, &wp->rbs_tx1_status); + } + } + } +#if 0 + for(x=0;xmax_timeslots;x++){ + if (wan_test_bit(7, &wp->rbs_tx[x])){ + card->wandev.fe_iface.set_rbsbits( + &wp->card->fe, + x+1, + wp->rbs_tx[x]); + wan_clear_bit(7, &wp->rbs_tx[x]); + if (wan_test_bit(7, &wp->rbs_tx1[x])){ + card->wandev.fe_iface.set_rbsbits( + &wp->card->fe, + x+1, + wp->rbs_tx1[x]); + wan_clear_bit(7, &wp->rbs_tx1[x]); + } + } + } +#endif + return 0; +} + +/****************************************************************************** +** wp_tdmv_ioctl() - +** +** OK +*/ +static int +#if defined(__FreeBSD__) || defined(__OpenBSD__) +wp_tdmv_ioctl(struct zt_chan *chan, unsigned int cmd, caddr_t data) +#else +wp_tdmv_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) +#endif +{ + int err = -ENOTTY; + wp_tdmv_softc_t *wp=NULL; + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + wp_tdmv_softc_t *echo_detect_wp = NULL; + int echo_detect_chan = 0; +#endif + + wp = chan->pvt; + + switch(cmd) + { + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(ZT_DCHAN_TX) + case ZT_DCHAN_TX: + + WAN_ASSERT(chan == NULL || chan->pvt == NULL); + wp = chan->pvt; + + if (wp->dchan_dev && wp->dchan_dev->hard_start_xmit){ + wp_tdmv_tx_dchan(chan, (int)data); + err=0; + }else{ + err=-EOPNOTSUPP; + } + break; +#endif + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + case SANGOMA_GET_ED_STATE: + DEBUG_ECHO("%s():SANGOMA_GET_ED_STATE\n", __FUNCTION__); + + WAN_ASSERT(chan == NULL || chan->pvt == NULL); + + echo_detect_wp = chan->pvt; + echo_detect_chan = chan->chanpos - 1; + + DEBUG_ECHO("on span: %d, chanpos: %d\n", echo_detect_wp->spanno, + echo_detect_chan); + + if(echo_detect_chan > 30 || echo_detect_chan < 0){ + err=-EOPNOTSUPP; + }else{ + wan_tdmv_t *wan_tdmv = &echo_detect_wp->card->wan_tdmv; + wan_tdmv_rxtx_pwr_t *pwr_rxtx = &wan_tdmv->chan_pwr[echo_detect_chan]; + + DEBUG_ECHO("%s():using %s table.\n", __FUNCTION__, + (chan->xlaw == __zt_mulaw ? "MULAW" : "ALAW")); + + /* This will be used when reporting Echo Cancellation state + from Asterisk CLI. + */ + chan->echo_detect_struct.echo_state = pwr_rxtx->current_state; + + DEBUG_ECHO("echo_state:%s\n", + TDMV_SAMPLE_STATE_DECODE(chan->echo_detect_struct.echo_state)); + + chan->echo_detect_struct.echo_present_samples_number = + pwr_rxtx->echo_present_samples_number_history; + chan->echo_detect_struct.echo_absent_samples_number = + pwr_rxtx->echo_absent_samples_number_history; + } + + err = 0; + break; +#endif /* CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER */ + + default: + /*DEBUG_EVENT("%s(): uknown cmd!\n", __FUNCTION__);*/ + err = -ENOTTY; + break; + } + return err; +} + +/****************************************************************************** +** wp_tdmv_hwec() - +** +** OK +*/ +static int wp_tdmv_hwec(struct zt_chan *chan, int enable) +{ + wp_tdmv_softc_t *wp = NULL; + sdla_t *card = NULL; + int channel = chan->chanpos; + int err = -EINVAL; + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wp = chan->pvt; + WAN_ASSERT2(wp->card == NULL, -ENODEV); + card = wp->card; + + if (card->wandev.ec_enable){ + DEBUG_TDMV("[TDMV]: %s: %s HW echo canceller on channel %d\n", + wp->devname, + (enable) ? "Enable" : "Disable", + channel); + if (!wp->ise1){ + channel--; + } + + /* The ec persist flag enables and disables + * persistent echo control. In persist mode + * echo cancellation is enabled regardless of + * asterisk. In persist mode off asterisk + * controls hardware echo cancellation */ + if (card->hwec_conf.persist_disable || IS_CHAN_HARDHDLC(chan)) { + err = card->wandev.ec_enable(card, enable, channel); + } else { + err = 0; + } + } + + return err; +} + +/****************************************************************************** +** wp_tdmv_open() - +** +** OK +*/ +static int wp_tdmv_open(struct zt_chan *chan) +{ + wp_tdmv_softc_t *wp = NULL; + sdla_t *card = NULL; + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wp = chan->pvt; + WAN_ASSERT2(wp->card == NULL, -ENODEV); + card = wp->card; + wp->usecount++; + DEBUG_TDMV("%s: Open (usecount=%d, channo=%d, chanpos=%d)...\n", + wp->devname, + wp->usecount, + chan->channo, + chan->chanpos); + return 0; +} + + +/****************************************************************************** +** wp_tdmv_close() - +** +** OK +*/ +static int wp_tdmv_close(struct zt_chan *chan) +{ + wp_tdmv_softc_t* wp = NULL; + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wp = chan->pvt; + wp->usecount--; + DEBUG_TDMV("%s: Close (usecount=%d, channo=%d, chanpos=%d)...\n", + wp->devname, + wp->usecount, + chan->channo, + chan->chanpos); + return 0; +} + +/****************************************************************************** +** wp_tdmv_release() - +** +** OK +*/ +static void wp_tdmv_release(wp_tdmv_softc_t *wp) +{ + WAN_ASSERT1(wp == NULL); + if (wan_test_bit(WP_TDMV_REGISTER, &wp->flags)){ + DEBUG_EVENT("%s: Unregister Wanpipe device from Zaptel!\n", + wp->devname); + wan_clear_bit(WP_TDMV_SIG_POLL, &wp->flags); + wan_clear_bit(WP_TDMV_REGISTER, &wp->flags); + zt_unregister(&wp->span); + wan_clear_bit(WP_TDMV_REGISTER, &wp->flags); + } + wan_free(wp); +} + +static inline void start_alarm(wp_tdmv_softc_t* wp) +{ + WAN_ASSERT1(wp == NULL); +#ifdef FANCY_ALARM + wp->alarmpos = 0; +#endif + wp->blinktimer = 0; +} + +static inline void stop_alarm(wp_tdmv_softc_t* wp) +{ + WAN_ASSERT1(wp == NULL); +#ifdef FANCY_ALARM + wp->alarmpos = 0; +#endif + wp->blinktimer = 0; +} + +/************************************************************************************ + * Channelized code for rx/tx + * *********************************************************************************/ + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) +/****************************************************************************** +** wp_tdmv_rx_dchan() - +** +** OK +*/ +static int wp_tdmv_rx_dchan(wan_tdmv_t *wan_tdmv, int channo, + unsigned char *rxbuf, unsigned int len) +{ + wp_tdmv_softc_t *wp = wan_tdmv->sc; + struct zt_chan *chan = NULL, *ms = NULL; + wan_smp_flag_t smp_flags; + unsigned char *buf = NULL; + int oldbuf; + int i, left; + + WAN_ASSERT(wp == NULL); + + if (!wan_test_bit(channo, &wp->dchan_map)) { + DEBUG_EVENT("%s: Internal Error: DCHAN Mismatch channo=%i 0x%08X\n", + wp->devname,channo,wp->dchan_map); + return -EINVAL; + } + + chan = &wp->chans[channo]; + WAN_ASSERT(chan == NULL || chan->master == NULL); + ms = chan->master; + + if (!IS_TDMV_UP(wp)){ + DEBUG_TDMV("%s: Asterisk is not running!\n", + wp->devname); + return -EINVAL; + } + + if (!IS_CHAN_HARDHDLC(ms)){ + DEBUG_TDMV("%s: ERROR: %s not defined as D-CHAN!\n", + wp->devname, ms->name); + return -EINVAL; + } + + if (ms->inreadbuf < 0){ + return -EINVAL; + } + + if (ms->inreadbuf >= ZT_MAX_NUM_BUFS){ + DEBUG_EVENT("%s: RX buffer (%s) is out of range (%d-%d)!\n", + wp->devname, ms->name, ms->inreadbuf,ZT_MAX_NUM_BUFS); + return -EINVAL; + } + + /* FIXME wan_spin_lock_irqsave(&wp->tx_rx_lock, smp_flags); */ + wan_spin_lock_irq(&chan->lock, &smp_flags); + buf = ms->readbuf[ms->inreadbuf]; + left = ms->blocksize - ms->readidx[ms->inreadbuf]; + if (len + 2 > left) { + DEBUG_EVENT("%s: ERROR: Not ehough space for RX HDLC packet (%d:%d)!\n", + wp->devname, len+2, left); + wan_spin_unlock_irq(&chan->lock, &smp_flags); + return -EINVAL; + } + for(i = 0; i < len; i++){ + buf[ms->readidx[ms->inreadbuf]++] = rxbuf[i]; + } + /* Add extra 2 bytes for checksum */ + buf[ms->readidx[ms->inreadbuf]++] = 0x00; + buf[ms->readidx[ms->inreadbuf]++] = 0x00; + + oldbuf = ms->inreadbuf; + ms->readn[ms->inreadbuf] = ms->readidx[ms->inreadbuf]; + ms->inreadbuf = (ms->inreadbuf + 1) % ms->numbufs; + if (ms->inreadbuf == ms->outreadbuf) { + /* Whoops, we're full, and have no where else + to store into at the moment. We'll drop it + until there's a buffer available */ + ms->inreadbuf = -1; + /* Enable the receiver in case they've got POLICY_WHEN_FULL */ + ms->rxdisable = 0; + } + if (ms->outreadbuf < 0) { /* start out buffer if not already */ + ms->outreadbuf = oldbuf; + } + /* FIXME wan_spin_unlock_irq(&wp->tx_rx_lock, &smp_flags); */ + wan_spin_unlock_irq(&chan->lock, &smp_flags); + if (!ms->rxdisable) { /* if receiver enabled */ + DEBUG_TDMV("%s: HDLC block is ready!\n", + wp->devname); + /* Notify a blocked reader that there is data available + to be read, unless we're waiting for it to be full */ +#if defined(__LINUX__) + wake_up_interruptible(&ms->readbufq); + wake_up_interruptible(&ms->sel); + if (ms->iomask & ZT_IOMUX_READ) + wake_up_interruptible(&ms->eventbufq); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) + wakeup(&ms->readbufq); + wakeup(&ms->sel); + if (ms->iomask & ZT_IOMUX_READ) + wakeup(&ms->eventbufq); + +#endif + } + return 0; +} +#endif + + + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) +static void wp_tdmv_tx_hdlc_hard(struct zt_chan *chan) +{ + wp_tdmv_softc_t *wp = NULL; + netskb_t *skb = NULL; + unsigned char *data = NULL; + int size = 0, err = 0, res = 0; + + WAN_ASSERT_VOID(chan == NULL); + WAN_ASSERT_VOID(chan->pvt == NULL); + wp = chan->pvt; + WAN_ASSERT_VOID(wp->dchan_dev == NULL); + + size = chan->writen[chan->outwritebuf] - chan->writeidx[chan->outwritebuf]-2; + skb = wan_skb_alloc(size+1); + if (skb == NULL){ + return; + } + data = wan_skb_put(skb, size); + res = zt_hdlc_getbuf(chan, data, &size); + if (res == 0){ + DEBUG_EVENT("%s: ERROR: TX HW DCHAN %d bytes (res %d)\n", + wp->devname, size, res); + } + err = wp->dchan_dev->hard_start_xmit(skb, wp->dchan_dev); + if (err){ + wan_skb_free(skb); + } + return; +} +#endif + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(ZT_DCHAN_TX) +static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len) +{ + wp_tdmv_softc_t *wp = NULL; + netskb_t *skb = NULL; + wan_smp_flag_t smp_flags; + unsigned char *data = NULL; + int err = 0; + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wp = chan->pvt; + WAN_ASSERT(wp->dchan_dev == NULL); + + + if (len <= 2){ + return -EINVAL; + } + len -= 2; /* Remove checksum */ + + skb = wan_skb_alloc(len+1); + if (skb == NULL){ + return -ENOMEM; + } + data = wan_skb_put(skb, len); + wan_spin_lock_irq(&chan->lock, &smp_flags); + memcpy(data, chan->writebuf[chan->inwritebuf], len); + wan_spin_unlock_irq(&chan->lock, &smp_flags); +#if 0 + { + int i; + DEBUG_EVENT("TX DCHAN: "); + for(i = 0; i < len; i++){ + _DEBUG_EVENT("%02X ", data[i]); + } + _DEBUG_EVENT("\n"); + } +#endif + if (skb){ + err = wp->dchan_dev->hard_start_xmit(skb, wp->dchan_dev); + if (err){ + wan_skb_free(skb); + } + } + + return err; +} +#endif + + + +/****************************************************************************** +** wp_tdmv_rx_chan() - +** +** OK +*/ +static int wp_tdmv_rx_chan(wan_tdmv_t *wan_tdmv, int channo, + unsigned char *rxbuf, + unsigned char *txbuf) +{ + wp_tdmv_softc_t *wp = wan_tdmv->sc; + sdla_t *card; + + WAN_ASSERT2(wp == NULL, -EINVAL); + WAN_ASSERT2(channo < 0, -EINVAL); + WAN_ASSERT2(channo > 31, -EINVAL); + + if (!IS_TDMV_UP(wp)){ + return -EINVAL; + } + card = wp->card; + + if (wp->channelized == WAN_TRUE){ +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + wan_tdmv_rxtx_pwr_t *pwr_rxtx = &wan_tdmv->chan_pwr[channo]; +#endif + + wp->chans[channo].readchunk = rxbuf; + wp->chans[channo].writechunk = txbuf; + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + wp_tdmv_echo_check(wan_tdmv, &wp->chans[channo], channo); +#endif + + /* If using hwec do not even call ec chunk */ + if ((!card->wandev.ec_enable || card->wandev.ec_enable_map == 0) && + !wan_test_bit(channo, &wp->echo_off_map)) { +/*Echo spike starts at 25bytes*/ +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + if(pwr_rxtx->current_state != ECHO_ABSENT){ +#endif +#if 0 +/* Echo spike starts at 16 bytes */ + + zt_ec_chunk( + &wp->chans[channo], + wp->chans[channo].readchunk, + wp->chans[channo].writechunk); +#endif + +#if 1 +/*Echo spike starts at 9 bytes*/ + zt_ec_chunk( + &wp->chans[channo], + wp->chans[channo].readchunk, + wp->ec_chunk1[channo]); + memcpy( + wp->ec_chunk1[channo], + wp->chans[channo].writechunk, + ZT_CHUNKSIZE); +#endif + +#if 0 +/*Echo spike starts at bytes*/ + zt_ec_chunk( + &wp->chans[channo], + wp->chans[channo].readchunk, + wp->ec_chunk1[channo]); + memcpy( + wp->ec_chunk1[channo], + wp->ec_chunk2[channo], + ZT_CHUNKSIZE); + + memcpy( + wp->ec_chunk2[channo], + wp->chans[channo].writechunk, + ZT_CHUNKSIZE); +#endif + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + } /* if(pwr_rxtx->current_state != ECHO_ABSENT) */ +#endif + } /* if (!wan_test_bit(channo, &wp->echo_off_map)) */ + }else{ + int x, channels = wp->span.channels; + + wp->tx_unchan = txbuf; + wp_tdmv_rxcopy(wan_tdmv, rxbuf, wp->max_rxtx_len); + + if (!wp->echo_off_map){ + for (x = 0; x < channels; x++){ +#if 0 + /* This code never runs. Instead wp_tdmv_rx_chan() + ** is called for A101/A102. All Echo Detection is + ** done there for A101/A102. */ + wp_tdmv_echo_check(wan_tdmv, &wp->chans[0], x); +#endif + + zt_ec_chunk( + &wp->chans[x], + wp->chans[x].readchunk, + wp->chans[x].writechunk); + +#if 0 + zt_ec_chunk( + &wp->chans[x], + wp->chans[x].readchunk, + wp->ec_chunk1[x]); + memcpy( + wp->ec_chunk1[x], + wp->chans[x].writechunk, + ZT_CHUNKSIZE); +#endif + } + }/* if() */ + }/* if() */ + + return 0; +} + +static int wp_tdmv_span_buf_rotate(void *pcard, u32 buf_sz, unsigned long mask) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t *wp = NULL; + int x; + unsigned int rx_offset, tx_offset; + void *ptr; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wp = wan_tdmv->sc; + + rx_offset = buf_sz * card->u.aft.tdm_rx_dma_toggle; + tx_offset = buf_sz * card->u.aft.tdm_tx_dma_toggle; + + for (x = 0; x < 32; x ++) { + if (wan_test_bit(x,&wp->timeslot_map)) { + + if (card->u.aft.tdmv_dchan && + (card->u.aft.tdmv_dchan-1) == x) { + continue; + } + + wan_spin_lock(&wp->chans[x].lock); + + ptr=(void*)((((unsigned long)wp->chans[x].readchunk) & ~(mask)) + rx_offset); + wp->chans[x].readchunk = ptr; + ptr=(void*)((((unsigned long)wp->chans[x].writechunk) & ~(mask)) + tx_offset); + wp->chans[x].writechunk = ptr; + + wan_spin_unlock(&wp->chans[x].lock); + +#if defined(__LINUX__) + prefetch(wp->chans[x].readchunk); + prefetch(wp->chans[x].writechunk); +#endif + + } + } + + + return 0; +} + +static int wp_tdmv_ec_span(void *pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t *wp = NULL; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wp = wan_tdmv->sc; + + zt_ec_span(&wp->span); + + return 0; + +} + +/****************************************************************************** +** wp_tdmv_rx_tx_span() - +** +** OK +*/ +static int wp_tdmv_rx_tx_span(void *pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t *wp = NULL; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wp = wan_tdmv->sc; + + wp->intcount++; + zt_receive(&wp->span); + zt_transmit(&wp->span); + + if (wp->channelized == WAN_FALSE){ + wp_tdmv_txcopy(wan_tdmv, + wp->tx_unchan, + wp->max_rxtx_len); + } + + if (wan_test_bit(WP_TDMV_RBS_UPDATE, &wp->flags)){ + DEBUG_TEST("%s: %s:%d: Updating RBS status \n", + wp->devname, + __FUNCTION__,__LINE__); + if (card->wandev.fe_iface.report_rbsbits){ + card->wandev.fe_iface.report_rbsbits(&card->fe); + } + wan_clear_bit(WP_TDMV_RBS_UPDATE, &wp->flags); + wan_clear_bit(WP_TDMV_RBS_BUSY, &wp->flags); + } + return 0; +} + + +/****************************************************************************** +** wp_tdmv_init() - +* +** OK +*/ +static int wp_tdmv_init(void* pcard, wanif_conf_t *conf) +{ + return -EINVAL; +} + diff --git a/patches/kdrivers/src/net/sdla_te1.c b/patches/kdrivers/src/net/sdla_te1.c index 2a6a8f9..77be60b 100644 --- a/patches/kdrivers/src/net/sdla_te1.c +++ b/patches/kdrivers/src/net/sdla_te1.c @@ -84,6 +84,8 @@ /****************************************************************************** * DEFINES AND MACROS ******************************************************************************/ +#define WAN_TE1_IGNORE_RLPS_ALOS + #define FIRST_SAMPLE 0 #define LAST_SAMPLE 23 #define FIRST_UI 0 @@ -197,7 +199,7 @@ static int te_reg_verify = 0; #define WAN_TE1_FRAMED_ALARMS (WAN_TE_BIT_RED_ALARM | WAN_TE_BIT_OOF_ALARM) -#define WAN_TE1_UNFRAMED_ALARMS (WAN_TE_BIT_RED_ALARM) +#define WAN_TE1_UNFRAMED_ALARMS (WAN_TE_BIT_RED_ALARM | WAN_TE_BIT_LOS_ALARM) #if 0 #define TE1_FRAME_ALARM (\ @@ -3617,9 +3619,17 @@ static int sdla_pmc4351_te_config(sdla_fe_t *fe, u16 adapter_type) } /* RLPS Configuration and Status (Reg 0xF8) */ + /* AF Nov 2007 + ** Set SQUELCHE to 1. This forces RLPS to stop sending pulses + ** to CDRC during ALOS conditions */ +#if defined (WAN_TE1_IGNORE_RLPS_ALOS) WRITE_REG(REG_RLPS_CFG_STATUS, - BIT_RLPS_CFG_STATUS_LONGE/* | - BIT_RLPS_CFG_STATUS_SQUELCHE*/); + BIT_RLPS_CFG_STATUS_LONGE | + BIT_RLPS_CFG_STATUS_SQUELCHE); +#else + WRITE_REG(REG_RLPS_CFG_STATUS, + BIT_RLPS_CFG_STATUS_LONGE); +#endif /* RLPS ALOS Detection/Clearance Thresholds (Reg 0xF9) */ /* NC: Aug 20 2003: @@ -3922,9 +3932,17 @@ static int sdla_pmc4354_te_config(sdla_fe_t *fe, u16 adapter_type) } /* RLPS Configuration and Status (Reg 0xQF8) */ - WRITE_REG(REG_RLPS_CFG_STATUS, - BIT_RLPS_CFG_STATUS_LONGE/* | - BIT_RLPS_CFG_STATUS_SQUELCHE*/); + /* AF Nov 2007 + ** Set SQUELCHE to 1. This forces RLPS to stop sending pulses + ** to CDRC during ALOS conditions */ +#if defined (WAN_TE1_IGNORE_RLPS_ALOS) + WRITE_REG(REG_RLPS_CFG_STATUS, + BIT_RLPS_CFG_STATUS_LONGE | + BIT_RLPS_CFG_STATUS_SQUELCHE); +#else + WRITE_REG(REG_RLPS_CFG_STATUS, + BIT_RLPS_CFG_STATUS_LONGE); +#endif /* RLPS ALOS Detection/Clearance Thresholds (Reg 0xQF9) */ /* NC: Aug 20 2003: @@ -6404,7 +6422,15 @@ sdla_te_add_event(sdla_fe_t *fe, sdla_fe_timer_event_t *fe_event) */ static int sdla_te_add_timer(sdla_fe_t* fe, unsigned long delay) { - int err; + int err=0; + + if (wan_test_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical)){ + return 0; + } + + if (wan_test_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical)) { + return 0; + } err = wan_add_timer(&fe->timer, delay * HZ / 1000); if (err){ diff --git a/patches/kdrivers/src/net/sdla_xilinx.c b/patches/kdrivers/src/net/sdla_xilinx.c index 9aad4a4..0cfcff4 100644 --- a/patches/kdrivers/src/net/sdla_xilinx.c +++ b/patches/kdrivers/src/net/sdla_xilinx.c @@ -398,6 +398,7 @@ static int aft_tdmv_free(sdla_t *card); static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf); static int aft_tdmv_if_free(sdla_t *card, private_area_t *chan); static void aft_critical_shutdown (sdla_t *card); +static int digital_loop_test(sdla_t* card,wan_udp_pkt_t* wan_udp_pkt); #ifdef AFT_TDM_API_SUPPORT static int aft_read_rbs_bits(void *chan_ptr, u32 ch, u8 *rbs_bits); @@ -5151,11 +5152,10 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, break; case DIGITAL_LOOPTEST: - wan_udp_pkt->wan_udp_return_code = 0; - DEBUG_EVENT("Ready to send some data!!!\n"); + wan_udp_pkt->wan_udp_return_code = + digital_loop_test(card,wan_udp_pkt); break; - case AFT_MODEM_STATUS: wan_udp_pkt->wan_udp_return_code = 0; if (card->wandev.state == WAN_CONNECTED){ @@ -7583,5 +7583,75 @@ static void aft_critical_shutdown (sdla_t *card) +static int digital_loop_test(sdla_t* card,wan_udp_pkt_t* wan_udp_pkt) +{ + netskb_t* skb; + netdevice_t* dev; + char* buf; + private_area_t *chan; + + dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head)); + if (dev == NULL) { + return 1; + } + chan = wan_netif_priv(dev); + if (chan == NULL) { + return 1; + } + + if (chan->common.state != WAN_CONNECTED) { + DEBUG_EVENT("%s: Loop test failed: dev not connected!\n", + card->devname); + return 2; + } + + skb = wan_skb_alloc(wan_udp_pkt->wan_udp_data_len+100); + if (skb == NULL) { + return 3; + } + + switch (chan->common.usedby) { + + case API: + wan_skb_push(skb, sizeof(api_rx_hdr_t)); + break; + + case STACK: + case WANPIPE: + break; + + case TDM_VOICE: + case TDM_VOICE_API: + case TDM_VOICE_DCHAN: + if (card->u.aft.tdmv_dchan) { + break; + } else { + DEBUG_EVENT("%s: Loop test failed: no dchan in TDMV mode!\n", + card->devname); + } + /* Fall into the default case */ + + default: + DEBUG_EVENT("%s: Loop test failed: invalid operation mode!\n", + card->devname); + wan_skb_free(skb); + return 4; + } + + buf = wan_skb_put(skb, wan_udp_pkt->wan_udp_data_len); + memcpy(buf, wan_udp_pkt->wan_udp_data, wan_udp_pkt->wan_udp_data_len); + + + skb->next = skb->prev = NULL; + skb->dev = dev; + skb->protocol = htons(ETH_P_IP); + wan_skb_reset_mac_header(skb); + dev_queue_xmit(skb); + + return 0; +} + + + /****** End ****************************************************************/ diff --git a/patches/kdrivers/src/net/sdladrv.c b/patches/kdrivers/src/net/sdladrv.c index 060d060..c384468 100644 --- a/patches/kdrivers/src/net/sdladrv.c +++ b/patches/kdrivers/src/net/sdladrv.c @@ -620,6 +620,9 @@ static void sdla_save_hw_probe (sdlahw_t* hw, int port) { sdla_hw_probe_t *tmp_hw_probe, *tmp; + unsigned char id_str[50]; + + memset(id_str,0,sizeof(id_str)); tmp_hw_probe = wan_malloc(sizeof(sdla_hw_probe_t)); if (!tmp_hw_probe) @@ -656,6 +659,17 @@ sdla_save_hw_probe (sdlahw_t* hw, int port) port ? "SEC" : "PRI", hw->hwcard->core_rev); } + + if (hw->hwcard->core_id == AFT_DS_FE_CORE_ID) { + strcpy(id_str,"DS26521"); + } else { + strcpy(id_str,"PMC4351"); + } + sprintf(&tmp_hw_probe->hw_info_verbose[0], "\n+%02d:%s:%s", + port+1, id_str, + AFT_PCITYPE_DECODE(hw->hwcard)); + + break; case A104_ADPTR_4TE1: @@ -685,6 +699,20 @@ sdla_save_hw_probe (sdlahw_t* hw, int port) hw->hwcard->core_rev ); /* line_no */ } + + if (hw->hwcard->core_id == AFT_DS_FE_CORE_ID) { + if (hw->hwcard->adptr_type == A108_ADPTR_8TE1) { + strcpy(id_str,"DS26528"); + } else { + strcpy(id_str,"DS26524"); + } + } else { + strcpy(id_str,"PMC4354"); + } + + sprintf(&tmp_hw_probe->hw_info_verbose[0], "\n+%02d:%s:%s", + port+1, id_str, + AFT_PCITYPE_DECODE(hw->hwcard)); break; case A200_ADPTR_ANALOG: @@ -838,9 +866,9 @@ static int sdla_save_Remora_hw_probe_verbose(sdlahw_t* hw, int port) for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no ++){ if (hw->hwcard->rm_mod_type[mod_no] == MOD_TYPE_FXS){ - sprintf(str, "\n+%02d:FXS", mod_no+1); + sprintf(str, "\n+%02d:FXS:%s", mod_no+1,AFT_PCITYPE_DECODE(hw->hwcard)); }else if (hw->hwcard->rm_mod_type[mod_no] == MOD_TYPE_FXO){ - sprintf(str, "\n+%02d:FXO", mod_no+1); + sprintf(str, "\n+%02d:FXO:%s", mod_no+1,AFT_PCITYPE_DECODE(hw->hwcard)); }else{ sprintf(str, "\n+%02d:EMPTY", mod_no+1); } diff --git a/patches/kdrivers/src/net/sdladrv_fe.c b/patches/kdrivers/src/net/sdladrv_fe.c index 75d8ad2..065fc5b 100644 --- a/patches/kdrivers/src/net/sdladrv_fe.c +++ b/patches/kdrivers/src/net/sdladrv_fe.c @@ -756,13 +756,11 @@ static u_int8_t __sdla_shark_rm_read_fe (void* phw, ...) } sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); #endif -#if 0 - DEBUG_EVENT("%s: %s: Module %d - Execute SPI command %08X\n", + DEBUG_TEST("%s: %s: Module %d - Execute SPI command %08X\n", hw->devname, __FUNCTION__, mod_no, data); -#endif for (i=0;i<10;i++){ WP_DELAY(10); sdla_bus_read_4(hw, SPI_INTERFACE_REG, &data); @@ -772,9 +770,9 @@ static u_int8_t __sdla_shark_rm_read_fe (void* phw, ...) } if (data & MOD_SPI_BUSY){ - DEBUG_EVENT("%s: Module %d: Critical Error (%s:%d)!\n", + DEBUG_EVENT("%s: Module %d: Critical Error (%s:%d) Data=0x%0X!\n", hw->devname, mod_no, - __FUNCTION__,__LINE__); + __FUNCTION__,__LINE__,data); return 0xFF; } diff --git a/patches/kdrivers/src/net/wanpipe_multppp.c b/patches/kdrivers/src/net/wanpipe_multppp.c index 584e6bb..d3f5125 100644 --- a/patches/kdrivers/src/net/wanpipe_multppp.c +++ b/patches/kdrivers/src/net/wanpipe_multppp.c @@ -996,6 +996,11 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) /* TE1 - Unconfiging, only on shutdown */ if (IS_TE1_CARD(card)) { + + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -3206,6 +3211,9 @@ static int config_chdlc (sdla_t *card) (IS_T1_CARD(card))?"T1":"E1"); return -EINVAL; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } if (IS_56K_CARD(card)) { @@ -3220,6 +3228,9 @@ static int config_chdlc (sdla_t *card) card->devname); return -EINVAL; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } @@ -3251,7 +3262,7 @@ static int config_chdlc (sdla_t *card) port_set_state(card, WAN_DISCONNECTED); return 0; } - }else{ + } else { if (chdlc_comm_enable(card) != 0) { printk(KERN_INFO "%s: Failed to enable chdlc communications!\n", card->devname); diff --git a/patches/kdrivers/src/wan_aften/wan_aften_src.o b/patches/kdrivers/src/wan_aften/wan_aften_src.o index 17f1f1b..e214ece 100644 Binary files a/patches/kdrivers/src/wan_aften/wan_aften_src.o and b/patches/kdrivers/src/wan_aften/wan_aften_src.o differ diff --git a/patches/kdrivers/src/wan_aften/wanpipe_linux_iface.o b/patches/kdrivers/src/wan_aften/wanpipe_linux_iface.o index 3adea04..26e58a3 100644 Binary files a/patches/kdrivers/src/wan_aften/wanpipe_linux_iface.o and b/patches/kdrivers/src/wan_aften/wanpipe_linux_iface.o differ diff --git a/patches/kdrivers/src/wanrouter/.af_wanpipe_src.o.d b/patches/kdrivers/src/wanrouter/.af_wanpipe_src.o.d deleted file mode 100644 index 9f2adf5..0000000 --- a/patches/kdrivers/src/wanrouter/.af_wanpipe_src.o.d +++ /dev/null @@ -1,157 +0,0 @@ -af_wanpipe_src.o: \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/src/net/../wanrouter/af_wanpipe_src.c \ - include/linux/autoconf.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_includes.h \ - include/linux/init.h include/linux/compiler.h \ - include/linux/compiler-gcc4.h include/linux/compiler-gcc.h \ - include/linux/version.h include/linux/module.h include/linux/sched.h \ - include/linux/auxvec.h include/asm/auxvec.h include/asm/param.h \ - include/linux/capability.h include/linux/types.h \ - include/linux/posix_types.h include/linux/stddef.h \ - include/asm/posix_types.h include/asm/types.h include/linux/spinlock.h \ - include/linux/preempt.h include/linux/thread_info.h \ - include/linux/bitops.h include/asm/bitops.h include/asm/alternative.h \ - include/asm-generic/bitops/sched.h include/asm-generic/bitops/hweight.h \ - include/asm-generic/bitops/fls64.h \ - include/asm-generic/bitops/ext2-non-atomic.h \ - include/asm-generic/bitops/le.h include/asm/byteorder.h \ - include/linux/byteorder/little_endian.h include/linux/byteorder/swab.h \ - include/linux/byteorder/generic.h include/asm-generic/bitops/minix.h \ - include/asm/thread_info.h include/asm/page.h \ - include/asm-generic/memory_model.h include/asm-generic/page.h \ - include/asm/processor.h include/asm/vm86.h include/asm/math_emu.h \ - include/asm/sigcontext.h include/asm/segment.h include/asm/cpufeature.h \ - include/asm/msr.h include/asm/system.h include/linux/kernel.h \ - /usr/lib/gcc/i386-redhat-linux/4.1.1/include/stdarg.h \ - include/linux/linkage.h include/asm/linkage.h include/asm/bug.h \ - include/asm-generic/bug.h include/linux/irqflags.h \ - include/asm/irqflags.h include/linux/cache.h include/asm/cache.h \ - include/linux/threads.h include/asm/percpu.h \ - include/asm-generic/percpu.h include/linux/cpumask.h \ - include/linux/bitmap.h include/linux/string.h include/asm/string.h \ - include/linux/stringify.h include/linux/spinlock_types.h \ - include/linux/lockdep.h include/linux/list.h include/linux/poison.h \ - include/linux/prefetch.h include/linux/debug_locks.h \ - include/linux/stacktrace.h include/asm/spinlock_types.h \ - include/asm/spinlock.h include/asm/atomic.h \ - include/asm-generic/atomic.h include/asm/rwlock.h \ - include/linux/spinlock_api_smp.h include/asm/current.h \ - include/linux/timex.h include/linux/time.h include/linux/seqlock.h \ - include/asm/timex.h include/asm/tsc.h include/linux/jiffies.h \ - include/linux/calc64.h include/asm/div64.h include/linux/rbtree.h \ - include/linux/errno.h include/asm/errno.h include/asm-generic/errno.h \ - include/asm-generic/errno-base.h include/linux/nodemask.h \ - include/linux/numa.h include/asm/semaphore.h include/linux/wait.h \ - include/linux/rwsem.h include/asm/rwsem.h include/asm/ptrace.h \ - include/asm/mmu.h include/asm/cputime.h include/asm-generic/cputime.h \ - include/linux/smp.h include/asm/smp.h include/asm/fixmap.h \ - include/asm/acpi.h include/acpi/pdc_intel.h include/asm/apicdef.h \ - include/asm/kmap_types.h include/asm/mpspec.h include/asm/mpspec_def.h \ - include/asm-i386/mach-generic/mach_mpspec.h include/asm/io_apic.h \ - include/asm/apic.h include/linux/pm.h \ - include/asm-i386/mach-generic/mach_apicdef.h include/asm/genapic.h \ - include/linux/sem.h include/linux/ipc.h include/asm/ipcbuf.h \ - include/asm/sembuf.h include/linux/signal.h include/asm/signal.h \ - include/asm-generic/signal.h include/asm/siginfo.h \ - include/asm-generic/siginfo.h include/linux/securebits.h \ - include/linux/fs_struct.h include/linux/completion.h \ - include/linux/pid.h include/linux/rcupdate.h include/linux/percpu.h \ - include/linux/slab.h include/linux/gfp.h include/linux/mmzone.h \ - include/linux/memory_hotplug.h include/linux/notifier.h \ - include/linux/mutex.h include/linux/topology.h include/asm/topology.h \ - include/asm-generic/topology.h include/linux/kmalloc_sizes.h \ - include/linux/seccomp.h include/linux/futex.h include/linux/rtmutex.h \ - include/linux/plist.h include/linux/param.h include/linux/resource.h \ - include/asm/resource.h include/asm-generic/resource.h \ - include/linux/timer.h include/linux/hrtimer.h include/linux/ktime.h \ - include/linux/aio.h include/linux/workqueue.h include/linux/aio_abi.h \ - include/linux/sysdev.h include/linux/kobject.h include/linux/sysfs.h \ - include/linux/kref.h include/linux/stat.h include/asm/stat.h \ - include/linux/kmod.h include/linux/elf.h include/linux/elf-em.h \ - include/asm/elf.h include/asm/user.h include/linux/utsname.h \ - include/asm/desc.h include/asm/ldt.h include/linux/moduleparam.h \ - include/asm/local.h include/asm/module.h include/linux/mm.h \ - include/linux/prio_tree.h include/linux/fs.h include/linux/limits.h \ - include/linux/ioctl.h include/asm/ioctl.h include/asm-generic/ioctl.h \ - include/linux/kdev_t.h include/linux/dcache.h \ - include/linux/radix-tree.h include/linux/quota.h \ - include/linux/dqblk_xfs.h include/linux/dqblk_v1.h \ - include/linux/dqblk_v2.h include/linux/nfs_fs_i.h include/linux/nfs.h \ - include/linux/sunrpc/msg_prot.h include/linux/fcntl.h \ - include/asm/fcntl.h include/asm-generic/fcntl.h include/linux/err.h \ - include/linux/backing-dev.h include/asm/pgtable.h \ - include/asm/pgtable-2level-defs.h include/asm/pgtable-2level.h \ - include/asm-generic/pgtable-nopmd.h include/asm-generic/pgtable-nopud.h \ - include/asm-generic/pgtable.h include/linux/page-flags.h \ - include/linux/vmstat.h include/linux/ctype.h include/net/ip.h \ - include/linux/ip.h include/linux/in.h include/linux/socket.h \ - include/asm/socket.h include/asm/sockios.h include/linux/sockios.h \ - include/linux/uio.h include/net/inet_sock.h include/net/flow.h \ - include/linux/in6.h include/net/sock.h include/linux/netdevice.h \ - include/linux/if.h include/linux/hdlc/ioctl.h include/linux/if_ether.h \ - include/linux/skbuff.h include/linux/highmem.h include/asm/cacheflush.h \ - include/asm/highmem.h include/linux/interrupt.h \ - include/linux/irqreturn.h include/linux/hardirq.h \ - include/linux/smp_lock.h include/asm/hardirq.h include/linux/irq.h \ - include/asm/irq.h include/asm-i386/mach-default/irq_vectors.h \ - include/asm-i386/mach-default/irq_vectors_limits.h include/asm/hw_irq.h \ - include/linux/profile.h include/asm/sections.h \ - include/asm-generic/sections.h include/linux/irq_cpustat.h \ - include/asm/tlbflush.h include/linux/poll.h include/asm/poll.h \ - include/asm/uaccess.h include/linux/net.h include/linux/sysctl.h \ - include/linux/textsearch.h include/net/checksum.h \ - include/asm/checksum.h include/linux/dmaengine.h include/linux/device.h \ - include/linux/ioport.h include/linux/klist.h include/linux/if_packet.h \ - include/linux/security.h include/linux/binfmts.h include/linux/shm.h \ - include/asm/shmparam.h include/asm/shmbuf.h include/linux/msg.h \ - include/asm/msgbuf.h include/linux/key.h include/linux/xfrm.h \ - include/linux/filter.h include/net/dst.h include/linux/rtnetlink.h \ - include/linux/netlink.h include/net/neighbour.h \ - include/linux/seq_file.h include/net/request_sock.h include/net/snmp.h \ - include/linux/snmp.h include/linux/ipv6.h include/linux/icmpv6.h \ - include/linux/tcp.h include/net/inet_connection_sock.h \ - include/net/inet_timewait_sock.h include/net/tcp_states.h \ - include/net/timewait_sock.h include/linux/udp.h include/net/if_inet6.h \ - include/net/protocol.h include/net/route.h include/net/inetpeer.h \ - include/linux/in_route.h include/linux/route.h include/linux/wireless.h \ - include/linux/inet.h include/asm/io.h include/asm-generic/iomap.h \ - include/linux/vmalloc.h include/asm/delay.h include/linux/pci.h \ - include/linux/pci_regs.h include/linux/pci_ids.h \ - include/linux/mod_devicetable.h include/linux/dmapool.h \ - include/asm/scatterlist.h include/asm/pci.h \ - include/asm-generic/pci-dma-compat.h include/linux/dma-mapping.h \ - include/asm/dma-mapping.h include/asm-generic/pci.h \ - include/linux/if_arp.h include/linux/pkt_sched.h \ - include/linux/etherdevice.h include/linux/random.h \ - include/linux/inetdevice.h include/net/inet_common.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_defines.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_version.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_kernel.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_debug.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_common.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_events.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_cfg.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/sdla_56k.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/sdla_te1.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/sdla_te3.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/sdla_remora.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/sdla_remora_proslic.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/sdla_front_end.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanrouter.h \ - include/linux/proc_fs.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/sdla_tdmv.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/sdlasfm.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/sdladrv.h \ - include/linux/serial.h include/linux/serialP.h include/linux/termios.h \ - include/asm/termios.h include/asm/termbits.h include/asm/ioctls.h \ - include/linux/circ_buf.h include/linux/serial_reg.h \ - include/asm/serial.h include/linux/tty.h include/linux/major.h \ - include/linux/tty_driver.h include/linux/cdev.h \ - include/linux/tty_ldisc.h include/linux/tty_flip.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/if_wanpipe_kernel.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/if_wanpipe.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/if_wanpipe_common.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_x25_kernel.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_dsp_kernel.h \ - /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/include/linux/wanpipe_x25_kernel.h diff --git a/patches/kdrivers/src/wanrouter/af_wanpipe_datascope.o b/patches/kdrivers/src/wanrouter/af_wanpipe_datascope.o index ede0a90..f061735 100644 Binary files a/patches/kdrivers/src/wanrouter/af_wanpipe_datascope.o and b/patches/kdrivers/src/wanrouter/af_wanpipe_datascope.o differ diff --git a/patches/kdrivers/src/wanrouter/af_wanpipe_src.o b/patches/kdrivers/src/wanrouter/af_wanpipe_src.o index 47788a6..d0567f9 100644 Binary files a/patches/kdrivers/src/wanrouter/af_wanpipe_src.o and b/patches/kdrivers/src/wanrouter/af_wanpipe_src.o differ diff --git a/patches/kdrivers/src/wanrouter/waniface.o b/patches/kdrivers/src/wanrouter/waniface.o index c49539d..dd5e9a8 100644 Binary files a/patches/kdrivers/src/wanrouter/waniface.o and b/patches/kdrivers/src/wanrouter/waniface.o differ diff --git a/patches/kdrivers/src/wanrouter/wanmain.o b/patches/kdrivers/src/wanrouter/wanmain.o index 52b1da8..2eed767 100644 Binary files a/patches/kdrivers/src/wanrouter/wanmain.o and b/patches/kdrivers/src/wanrouter/wanmain.o differ diff --git a/patches/kdrivers/src/wanrouter/wanproc.o b/patches/kdrivers/src/wanrouter/wanproc.o index 0496743..cf79737 100644 Binary files a/patches/kdrivers/src/wanrouter/wanproc.o and b/patches/kdrivers/src/wanrouter/wanproc.o differ diff --git a/patches/kdrivers/wanec/.tmp_versions/wanec.mod b/patches/kdrivers/wanec/.tmp_versions/wanec.mod index 24b40f1..f26d2db 100644 --- a/patches/kdrivers/wanec/.tmp_versions/wanec.mod +++ b/patches/kdrivers/wanec/.tmp_versions/wanec.mod @@ -1,2 +1,2 @@ -/root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/wanec.ko -/root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/wanec_iface.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/wanec_cmd.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/wanec_utils.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/wanec_dev.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/apilib/bt/octapi_bt0.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/apilib/largmath/octapi_largmath.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/apilib/llman/octapi_llman.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_events.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.o /root/development/3.2/wanpipe-3.2.1/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_user.o +/root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/wanec.ko +/root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/wanec_iface.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/wanec_cmd.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/wanec_utils.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/wanec_dev.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/apilib/bt/octapi_bt0.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/apilib/largmath/octapi_largmath.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/apilib/llman/octapi_llman.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_events.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.o /root/development/3.2/wanpipe-3.2.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_user.o diff --git a/patches/kdrivers/wanec/Makefile.Kbuild.Linux b/patches/kdrivers/wanec/Makefile.Kbuild.Linux index 8a77357..b88a52f 100644 --- a/patches/kdrivers/wanec/Makefile.Kbuild.Linux +++ b/patches/kdrivers/wanec/Makefile.Kbuild.Linux @@ -16,6 +16,8 @@ $(MODULE_NAME)-objs = $(OBJS) RM = @rm -rf JUNK = *~ *.bak DEADJOE +PWD := $(shell pwd) +SUBDIRS=$(PWD) # First pass, kernel Makefile reads module objects ifneq ($(KERNELRELEASE),) @@ -29,19 +31,19 @@ PWD := $(shell pwd) KBUILD_VERBOSE= all: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules clean: - $(shell find . -name '*.*o' | xargs rm) - $(shell find . -name '.*.o.cmd' | xargs rm) + $(shell find $(SUBDIRS) -name '*.*o' | xargs rm) + $(shell find $(SUBDIRS) -name '.*.o.cmd' | xargs rm) $(shell rm -f build.sh) - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) clean distclean: clean $(RM) $(JUNK) $(OBJS) help: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) help + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) help # Indents the kernel source the way linux/Documentation/CodingStyle.txt @@ -50,6 +52,6 @@ indent: indent -kr -i8 $($(MODULE_NAME)-objs:.o=.c) install: - $(MAKE) -C $(KDIR) M=$(PWD) modules_install + $(MAKE) -C $(KDIR) M=$(SUBDIRS) modules_install endif diff --git a/patches/kdrivers/wanec/modinfo/wanec.mod.c b/patches/kdrivers/wanec/modinfo/wanec.mod.c deleted file mode 100644 index e11db23..0000000 --- a/patches/kdrivers/wanec/modinfo/wanec.mod.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include - -MODULE_INFO(vermagic, VERMAGIC_STRING); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) || defined(WANPIPE_MOD_266_FORCE_UPDATE) -#undef unix -struct module __this_module -__attribute__((section(".gnu.linkonce.this_module"))) = { - .name = __stringify(KBUILD_MODNAME), - .init = init_module, -#ifdef CONFIG_MODULE_UNLOAD - .exit = cleanup_module, -#endif -}; -#endif - -static const struct modversion_info ____versions[] -__attribute__((section("__versions"))) = { - -}; - -static const char __module_depends[] -__attribute_used__ -__attribute__((section(".modinfo"))) = -"depends=wanrouter"; - diff --git a/patches/kdrivers/wanec/wanec.mod.c b/patches/kdrivers/wanec/wanec.mod.c index 4069700..f73e369 100644 --- a/patches/kdrivers/wanec/wanec.mod.c +++ b/patches/kdrivers/wanec/wanec.mod.c @@ -51,4 +51,4 @@ __attribute__((section(".modinfo"))) = "depends="; -MODULE_INFO(srcversion, "3287EDB9893E2DC512577FD"); +MODULE_INFO(srcversion, "4B81F8CBCF0FE7DE2D1F612"); diff --git a/patches/kdrivers/wanec/wanec_cmd.c b/patches/kdrivers/wanec/wanec_cmd.c index 1ef57f8..7341fbc 100644 --- a/patches/kdrivers/wanec/wanec_cmd.c +++ b/patches/kdrivers/wanec/wanec_cmd.c @@ -829,6 +829,9 @@ int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) (pcm_law_type == cOCT6100_PCM_U_LAW) ? "MULAW":"ALAW"); + DEBUG_EVENT("%s: Opening HW Echo Canceller (NoiseRed=%s)\n", + ec->name,card->hwec_conf.noise_reduction?"On":"Off"); + for(channel = 0; channel < ec->max_channels; channel++){ Oct6100ChannelOpenDef( &EchoChannelOpen ); @@ -871,12 +874,12 @@ int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) EchoChannelOpen.VqeConfig.fAcousticEcho = TRUE; #endif -#if defined(WANEC_ENABLE_NOISE_REDUCTION) -#warning "WAN HWEC NOISE Reduction Enabled" - EchoChannelOpen.VqeConfig.fSoutAdaptiveNoiseReduction = TRUE; -#else - EchoChannelOpen.VqeConfig.fSoutAdaptiveNoiseReduction = FALSE; -#endif + if (card->hwec_conf.noise_reduction) { + EchoChannelOpen.VqeConfig.fSoutAdaptiveNoiseReduction = TRUE; + } else { + EchoChannelOpen.VqeConfig.fSoutAdaptiveNoiseReduction = FALSE; + } + EchoChannelOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; /* cOCT6100_COMFORT_NOISE_NORMAL diff --git a/patches/sangoma-zaptel-patch.sh b/patches/sangoma-zaptel-patch.sh index 52fc041..b0c39a7 100755 --- a/patches/sangoma-zaptel-patch.sh +++ b/patches/sangoma-zaptel-patch.sh @@ -113,7 +113,26 @@ if [ "$ZAPTEL_DIR" == "" ]; then ZAPTEL_DIR=/usr/src/zaptel fi +cd $ZAPTEL_DIR +if [ -e $ZAPTEL_DIR/zaptel-base.c ]; then + ZAPTEL_C_FILE=zaptel-base.c +fi + + +eval "grep hdlc_hard_xmit $ZAPTEL_C_FILE > /dev/null 2> /dev/null" +if [ $? -eq 0 ] ; then + touch /etc/wanpipe/.zaphdlc + echo "Zaptel HW HDLC support detected" + exit 10 +else + if [ -e /etc/wanpipe/.zaphdlc ]; then + eval "rm -f /etc/wanpipe/.zaphdlc 2> /dev/null" + fi +fi + echo "Applying Sangoma DCHAN patch to $ZAPTEL_DIR" echo " " tdmv_apply_zaptel_dchan_patch + +exit $? diff --git a/rpmspec/wanpipe-mod.spec b/rpmspec/wanpipe-mod.spec index b71119b..cddb0c1 100644 --- a/rpmspec/wanpipe-mod.spec +++ b/rpmspec/wanpipe-mod.spec @@ -1,6 +1,6 @@ %define WANPIPE_VER wanpipe-modules %define name %{WANPIPE_VER} -%define version 3.2.1 +%define version 3.2.2 %define release 0 %define serial 1 %define MODULES_DIR /lib/modules @@ -50,6 +50,114 @@ echo "Wanpipe Modules located in %{MODULES_DIR}/%{KVERSION}" %changelog +* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.2 +======================================================================== + +- AFT Maxim Front end update + Implemented graceful recovery on short circuit. + +- AFT Driver update + Added a check for TDM IRQ timeout. + On some machines its possible for TDM IRQ to timeout. + +- SMG updated + Fixed wancfg_smg + MTU not properly set on ports 2 and up + Voice only ports were not being added to startup sequence + Updated for callweaver + +- Added Zaptel 1.4 HW HDLC Support + No Sangoma zaptel patch needed with Zaptel 1.4 + +- Added HWEC Noise flag in wanpipe config file + +- Updated SMG +- Updated E1 Unframed on Maxim Cards + +- Updates for AFT PMC and MAXIM framers + PMC - lowered LOS sensitivity + Fixes fake up/down state changes on + started inactive lines. + + MAXIM - lowered sensistivy + Fixes cable cross talk on 8 port cards. + - Enabled Unframed E1 + - Enabled Tri-State Mode + - Fixed loopback commands + +- Fixed HWEC_PERSIST_DISABLE + This option was broken in previous release + This option lets Asterisk control HWEC + on each call start/stop. + By default all hwec channels are enabled on + device startup. + +- Updated SMG/SS7 +- Updated loopback commands for AFT Maxim cards + +- Updated for AstLinux + The make file can now build all WAN and Voice Protocols + +- Fixed add_timer warnings for ALL AFT cards + Caused when a port is left in unconnected state. + +- Updated legacy protocols for new front end architecture + +- Updated Setup script + + +* Wed Oct 6 2007 Nenad Corbic - Stable - 3.2.1 +===================================================================== + +- Setup Zap Chunk Size Patch updated for Zaptel 1.4 + Patch allows running zaptel in 8,16,40,80 chunk size. + However wct drivers must be removed from compilation :) + Patch is now fixed for Zaptel 1.4 + +- Update to All AFT drivers for 64bit 2.6.22 kernel. + Updated affects: AFT A101/2/4/8/200/400 (all cards) + The major 2.6.20+ updates extend to 64bit as well. + Previous drivers segfaulted under 2.6.22 64bit + kernels. This does not affect you if you are running + kennels lower than 2.6.22. + +- Updated legacy drivers for 2.6.22 kernel + + + +* Wed Oct 3 2007 Nenad Corbic - Stable - 3.2.0 +===================================================================== + +- The Beta 3.1.X releases has now been declared as STABLE 3.2.X + +- Fixed AMI/D4 on MAXIM (A101/2/4/8D) cards +- Fixed A200/A400 tip/ring no dial tone issues. +- Fixed 2.6.22 support and above +- Fixed RPM Build post install issue +- Updated Setup install script + Option to build for zaptel: ./Setup zaptel +- Working E&M/RBS/CAS Channel Bank support for MAXIM (A101/2/4/8) cards. +- Fixed wanpipe crashing on system shutdown on some machines. + Caused by RedHat /var/lock/subsys mandatory lock file. +- New Firmware for all MAXIM Cards (A101/2/4/8D) + Firmware V33: Fixes EC Chip Security errors that can cause + PRI to go down on some computers. Firmware is backward compatible + to any previous release. +- Faxes/Modems working through hardware echo canceler. + Tested at 56K from one port to another. + New octasic update. +- Analog Network SYNC Feature for Fax Support + Analog cards can be synced to T1/E1 clock + from adjacent A101/2/4/8 cards for flawless faxing + from FXO/FXS to T1/E1. + +- Known Issues: + T1/E1 High Impedance Tap for MAXIM (A101/2/4/8D) cards. + It works on original PMC A101/2/4 cards + +For more info: http://wiki.sangoma.com + + * Mon Oct 1 2007 Nenad Corbic - Beta - 3.1.4.6 ==================================================================== diff --git a/rpmspec/wanpipe-util.spec b/rpmspec/wanpipe-util.spec index 13201fb..31181ac 100644 --- a/rpmspec/wanpipe-util.spec +++ b/rpmspec/wanpipe-util.spec @@ -1,11 +1,12 @@ %define KERNEL_VERSION %{?kern_ver} %define WANPIPE_VER wanpipe-util %define name %{WANPIPE_VER} -%define version 3.2.1 +%define version 3.2.2 %define release 0 %define serial 1 +%define ETC_DIR /etc +%define USR_DIR /usr %define UTILS_DIR /usr/sbin -%define UTILS_LOCAL_DIR /usr/local/sbin %define PROD_HOME /etc/wanpipe %define WANCFG_LIBS_DIR /etc/wanpipe/wancfg/lib %define API_DIR /etc/wanpipe/api @@ -237,13 +238,122 @@ install_init; %files +%{ETC_DIR} +%{USR_DIR} %{UTILS_DIR} -%{UTILS_LOCAL_DIR} %{PROD_HOME} %{DOCS_DIR} %changelog +* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.2 +======================================================================== + +- AFT Maxim Front end update + Implemented graceful recovery on short circuit. + +- AFT Driver update + Added a check for TDM IRQ timeout. + On some machines its possible for TDM IRQ to timeout. + +- SMG updated + Fixed wancfg_smg + MTU not properly set on ports 2 and up + Voice only ports were not being added to startup sequence + Updated for callweaver + +- Added Zaptel 1.4 HW HDLC Support + No Sangoma zaptel patch needed with Zaptel 1.4 + +- Added HWEC Noise flag in wanpipe config file + +- Updated SMG +- Updated E1 Unframed on Maxim Cards + +- Updates for AFT PMC and MAXIM framers + PMC - lowered LOS sensitivity + Fixes fake up/down state changes on + started inactive lines. + + MAXIM - lowered sensistivy + Fixes cable cross talk on 8 port cards. + - Enabled Unframed E1 + - Enabled Tri-State Mode + - Fixed loopback commands + +- Fixed HWEC_PERSIST_DISABLE + This option was broken in previous release + This option lets Asterisk control HWEC + on each call start/stop. + By default all hwec channels are enabled on + device startup. + +- Updated SMG/SS7 +- Updated loopback commands for AFT Maxim cards + +- Updated for AstLinux + The make file can now build all WAN and Voice Protocols + +- Fixed add_timer warnings for ALL AFT cards + Caused when a port is left in unconnected state. + +- Updated legacy protocols for new front end architecture + +- Updated Setup script + + +* Wed Oct 6 2007 Nenad Corbic - Stable - 3.2.1 +===================================================================== + +- Setup Zap Chunk Size Patch updated for Zaptel 1.4 + Patch allows running zaptel in 8,16,40,80 chunk size. + However wct drivers must be removed from compilation :) + Patch is now fixed for Zaptel 1.4 + +- Update to All AFT drivers for 64bit 2.6.22 kernel. + Updated affects: AFT A101/2/4/8/200/400 (all cards) + The major 2.6.20+ updates extend to 64bit as well. + Previous drivers segfaulted under 2.6.22 64bit + kernels. This does not affect you if you are running + kennels lower than 2.6.22. + +- Updated legacy drivers for 2.6.22 kernel + + + +* Wed Oct 3 2007 Nenad Corbic - Stable - 3.2.0 +===================================================================== + +- The Beta 3.1.X releases has now been declared as STABLE 3.2.X + +- Fixed AMI/D4 on MAXIM (A101/2/4/8D) cards +- Fixed A200/A400 tip/ring no dial tone issues. +- Fixed 2.6.22 support and above +- Fixed RPM Build post install issue +- Updated Setup install script + Option to build for zaptel: ./Setup zaptel +- Working E&M/RBS/CAS Channel Bank support for MAXIM (A101/2/4/8) cards. +- Fixed wanpipe crashing on system shutdown on some machines. + Caused by RedHat /var/lock/subsys mandatory lock file. +- New Firmware for all MAXIM Cards (A101/2/4/8D) + Firmware V33: Fixes EC Chip Security errors that can cause + PRI to go down on some computers. Firmware is backward compatible + to any previous release. +- Faxes/Modems working through hardware echo canceler. + Tested at 56K from one port to another. + New octasic update. +- Analog Network SYNC Feature for Fax Support + Analog cards can be synced to T1/E1 clock + from adjacent A101/2/4/8 cards for flawless faxing + from FXO/FXS to T1/E1. + +- Known Issues: + T1/E1 High Impedance Tap for MAXIM (A101/2/4/8D) cards. + It works on original PMC A101/2/4 cards + +For more info: http://wiki.sangoma.com + + * Mon Oct 1 2007 Nenad Corbic - Beta - 3.1.4.6 ==================================================================== diff --git a/rpmspec/wanpipe.spec b/rpmspec/wanpipe.spec index 7731c1a..48372cd 100644 --- a/rpmspec/wanpipe.spec +++ b/rpmspec/wanpipe.spec @@ -1,11 +1,12 @@ %define KERNEL_VERSION %{?kern_ver} %define WANPIPE_VER wanpipe %define name %{WANPIPE_VER} -%define version 3.2.1 +%define version 3.2.2 %define release 0 %define serial 1 %define UTILS_DIR /usr/sbin -%define UTILS_LOCAL_DIR /usr/local/sbin +%define ETC_DIR /etc +%define USR_DIR /usr %define PROD_HOME /etc/wanpipe %define WANCFG_LIBS_DIR /etc/wanpipe/lib %define API_DIR /etc/wanpipe/api @@ -244,15 +245,123 @@ install_init; %files %{UTILS_DIR} -%{UTILS_LOCAL_DIR} +%{ETC_DIR} +%{USR_DIR} %{PROD_HOME} %{DOCS_DIR} %{MODULES_DIR} %{USR_INCLUDE_DIR} -%{LIBSANGOMA_CONF} %changelog +* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.2 +======================================================================== + +- AFT Maxim Front end update + Implemented graceful recovery on short circuit. + +- AFT Driver update + Added a check for TDM IRQ timeout. + On some machines its possible for TDM IRQ to timeout. + +- SMG updated + Fixed wancfg_smg + MTU not properly set on ports 2 and up + Voice only ports were not being added to startup sequence + Updated for callweaver + +- Added Zaptel 1.4 HW HDLC Support + No Sangoma zaptel patch needed with Zaptel 1.4 + +- Added HWEC Noise flag in wanpipe config file + +- Updated SMG +- Updated E1 Unframed on Maxim Cards + +- Updates for AFT PMC and MAXIM framers + PMC - lowered LOS sensitivity + Fixes fake up/down state changes on + started inactive lines. + + MAXIM - lowered sensistivy + Fixes cable cross talk on 8 port cards. + - Enabled Unframed E1 + - Enabled Tri-State Mode + - Fixed loopback commands + +- Fixed HWEC_PERSIST_DISABLE + This option was broken in previous release + This option lets Asterisk control HWEC + on each call start/stop. + By default all hwec channels are enabled on + device startup. + +- Updated SMG/SS7 +- Updated loopback commands for AFT Maxim cards + +- Updated for AstLinux + The make file can now build all WAN and Voice Protocols + +- Fixed add_timer warnings for ALL AFT cards + Caused when a port is left in unconnected state. + +- Updated legacy protocols for new front end architecture + +- Updated Setup script + + +* Wed Oct 6 2007 Nenad Corbic - Stable - 3.2.1 +===================================================================== + +- Setup Zap Chunk Size Patch updated for Zaptel 1.4 + Patch allows running zaptel in 8,16,40,80 chunk size. + However wct drivers must be removed from compilation :) + Patch is now fixed for Zaptel 1.4 + +- Update to All AFT drivers for 64bit 2.6.22 kernel. + Updated affects: AFT A101/2/4/8/200/400 (all cards) + The major 2.6.20+ updates extend to 64bit as well. + Previous drivers segfaulted under 2.6.22 64bit + kernels. This does not affect you if you are running + kennels lower than 2.6.22. + +- Updated legacy drivers for 2.6.22 kernel + + + +* Wed Oct 3 2007 Nenad Corbic - Stable - 3.2.0 +===================================================================== + +- The Beta 3.1.X releases has now been declared as STABLE 3.2.X + +- Fixed AMI/D4 on MAXIM (A101/2/4/8D) cards +- Fixed A200/A400 tip/ring no dial tone issues. +- Fixed 2.6.22 support and above +- Fixed RPM Build post install issue +- Updated Setup install script + Option to build for zaptel: ./Setup zaptel +- Working E&M/RBS/CAS Channel Bank support for MAXIM (A101/2/4/8) cards. +- Fixed wanpipe crashing on system shutdown on some machines. + Caused by RedHat /var/lock/subsys mandatory lock file. +- New Firmware for all MAXIM Cards (A101/2/4/8D) + Firmware V33: Fixes EC Chip Security errors that can cause + PRI to go down on some computers. Firmware is backward compatible + to any previous release. +- Faxes/Modems working through hardware echo canceler. + Tested at 56K from one port to another. + New octasic update. +- Analog Network SYNC Feature for Fax Support + Analog cards can be synced to T1/E1 clock + from adjacent A101/2/4/8 cards for flawless faxing + from FXO/FXS to T1/E1. + +- Known Issues: + T1/E1 High Impedance Tap for MAXIM (A101/2/4/8D) cards. + It works on original PMC A101/2/4 cards + +For more info: http://wiki.sangoma.com + + * Mon Oct 1 2007 Nenad Corbic - Beta - 3.1.4.6 ==================================================================== diff --git a/samples/diff b/samples/diff deleted file mode 100644 index a7f8eb4..0000000 --- a/samples/diff +++ /dev/null @@ -1,1007 +0,0 @@ ---- wanrouter 2007-08-27 18:28:49.000000000 -0400 -+++ /usr/sbin/wanrouter 2007-09-14 12:39:15.000000000 -0400 -@@ -1,7 +1,8 @@ - #!/bin/bash -p -+ - # wanrouter WANPIPE WAN Router Initialization Script. - # --# copyright (c) 1999-2007, Sangoma Technologies Inc. -+# copyright (c) 1999-2002, Sangoma Technologies Inc. - # - # This program is free software; you can redistribute it and/or - # modify it under the terms of the GNU General Public License -@@ -119,6 +120,11 @@ - function cleanup () - { - eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" -+ -+ #Check module checks if modules are loaded and updates -+ #the subsys lock for LINUX -+ check_module -+ - exit $1 - } - -@@ -268,6 +274,28 @@ - return 0 - } - -+function check_module () { -+ -+ if [ $OSYSTEM = "Linux" ]; then -+ [ -d "$ROUTER_PROC" ] && { -+ touch $WAN_LOCK 2> /dev/null -+ return 0 -+ } -+ else -+ for i in $WAN_DRIVERS -+ do $MODULE_STAT | grep -q $i && { -+ touch $WAN_LOCK 2> /dev/null -+ return 0 -+ } -+ done -+ fi -+ -+ # Driver is not loaded -+ if [ -e $WAN_LOCK ]; then -+ rm -f $WAN_LOCK 2> /dev/null -+ fi -+ return 1; -+} - - function load_driver () { - -@@ -307,6 +335,19 @@ - return $err - } - -+#-------------------------------------------------------------------------- -+# Create character device /dev/wanrouter -+#-------------------------------------------------------------------------- -+create_cdev() -+{ -+ if [ $OSYSTEM = "FreeBSD" ]; then -+ [ ! -e "$CDEV_WANROUTER" ] && { -+ mknod $CDEV_WANROUTER c $CDEV_MAJOR $CDEV_MINOR -+ } -+ fi -+} -+ -+ - # ---------------------------------------------------------------------------- - # Start WAN wanrouter. - # o create log file -@@ -319,6 +360,11 @@ - { - local opt=${1:-NO} - -+ check_module -+ if [ $? -eq 0 ]; then -+ return 0 -+ fi -+ - if [ $opt != silent ]; then - echo "Starting WAN Router..." - echo "`date`: starting WAN router" >> $WAN_LOG -@@ -444,22 +490,13 @@ - echo "done." - fi - -+ # Create char devices (if needed) -+ create_cdev -+ - touch $WANPIPE_IS_RUNNING - return 0 - } - --#-------------------------------------------------------------------------- --# Create character device /dev/wanrouter --#-------------------------------------------------------------------------- --create_cdev() --{ -- if [ $OSYSTEM = "FreeBSD" ]; then -- [ ! -e "$CDEV_WANROUTER" ] && { -- mknod $CDEV_WANROUTER c $CDEV_MAJOR $CDEV_MINOR -- } -- fi --} -- - router_config() - { - # Configure router. -@@ -699,6 +736,186 @@ - } - } - -+# ---------------------------------------------------------------------------- -+# Configure devices (all or single). -+# ---------------------------------------------------------------------------- -+config_devices() -+{ -+ local devices=$* -+ -+ for dev in $devices; do -+ if [ $OSYSTEM = "Linux" ] && [ ! -e "$ROUTER_PROC/$dev" ]; then -+ echo -e "Error: Device $dev is not supported by kernel\n" -+ continue -+ fi -+ WAN_CONF=$WAN_CONF_DIR/$dev.conf -+ -+ check_file $WAN_CONF || cleanup 1 -+ -+ check_exists $dev -+ if [ $? -ne 0 ]; then -+ echo "Error: Device $dev does not exist/not allocated." -+ echo " Check the messages log for the number of probed " -+ echo " devices." -+ echo -+ continue -+ fi -+ -+ check_dev_running $dev -+ if [ $? -eq 0 ]; then -+ echo "Error: Device $dev is already running" -+ echo -e " Run 'wanrouter stop $dev' first\n" -+ continue -+ fi -+ -+ #Since we changed the name of dev above, -+ #we must check if we are running ft1 device, -+ #output a correct message -+ if [ $ft1_or_wanpipe -gt 0 ]; then -+ echo "Starting up device: $dev, FT1 config mode" -+ echo "Starting up device: $dev, FT1 config mode" >> $WAN_LOG -+ else -+ echo "Starting up device: $dev" -+ echo "Starting up device: $dev" >> $WAN_LOG -+ fi -+ -+ router_config $WAN_CONF $dev -+#NC: Jul 22 2003 -+#Just because one card -+#fails to load do not stop -+#other cards from loading -+# if [ $? -ne 0 ]; then -+# #echo "Exiting rc = 3" -+# cleanup 3 -+# fi -+ done -+ -+ return 0 -+} -+ -+# ---------------------------------------------------------------------------- -+# Unconfigure devices (all or single). -+# ---------------------------------------------------------------------------- -+unconfig_devices() -+{ -+ local devices=$* -+ -+ #Stop all routers but check if device -+ #is running first -+ for dev in $devices; do -+ WAN_CONF=$WAN_CONF_DIR/$dev.conf -+ -+ #If we are starting ft1 device there are no -+ #interfaces. -+ if [ $ft1_or_wanpipe -gt 0 ]; then -+ echo "Shutting down device: $dev, FT1 config mode" -+ echo "Shutting down device: $dev, FT1 config mode" >> $WAN_LOG -+ else -+ echo "Shutting down device: $dev" -+ echo "Shutting down device: $dev" >> $WAN_LOG -+ fi -+ router_unconfig $WAN_CONF $dev -+ -+ done -+ -+ #Check if any devices are still running -+ # If YES: don't unload the modules, just printout -+ # the list of active devices -+ # If NO: unload modules -+ -+ check_and_print_still_running && cleanup 0 -+ -+ cd $WAN_HOME -+ echo -e "No devices running, Unloading Modules" -+ remove_cdev -+ unload_module -+ -+ for dev in $devices; do -+ WAN_CONF=$WAN_CONF_DIR/$dev.conf -+ -+ INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` -+ for ifname in $INTERFACES; do -+ ifname=${ifname%%=*} -+ wanrouter_script stop $dev $ifname -+ done -+ wanrouter_script stop $dev -+ -+ done -+ -+ return 0 -+} -+ -+# ---------------------------------------------------------------------------- -+# Configure wan interfaces (all or single). -+# ---------------------------------------------------------------------------- -+config_interfaces() -+{ -+ local devices=$* -+ -+ for dev in $devices; do -+ -+ WAN_CONF=$WAN_CONF_DIR/$dev.conf -+ -+ check_file $WAN_CONF || cleanup 1 -+ -+ interf_config $dev $WAN_CONF -+ -+#NC: Jul 22 2003 -+#Just because one interface -+#fails to load, do not stop all -+#other interfaces. -+# if [ $? -ne 0 ]; then -+# cleanup 4 -+# fi -+ done -+ -+ for dev in $devices; do -+ WAN_CONF=$WAN_CONF_DIR/$dev.conf -+ INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` -+ for ifname in $INTERFACES; do -+ ifname=${ifname%%=*} -+ wanrouter_script start $dev $ifname -+ done -+ wanrouter_script start $dev -+ done -+ -+ return 0 -+} -+ -+# ---------------------------------------------------------------------------- -+# unconfigure interface (all or single). -+# ---------------------------------------------------------------------------- -+unconfig_interfaces() -+{ -+ local devices=$* -+ -+ #Stop all interfaces, but check whether -+ #device is running first -+ for dev in $devices; do -+ -+ if [ "$dev" = "" ]; then -+ continue; -+ fi -+ -+ WAN_CONF=$WAN_CONF_DIR/$dev.conf -+ -+ #Check that all configuration files exist -+ check_file $WAN_CONF || cleanup 1 -+ -+ check_exists $dev -+ if [ $? -eq 0 ]; then -+ check_dev_running $dev -+ if [ $? -eq 0 ]; then -+ WAN_CONF=$WAN_CONF_DIR/$dev.conf -+ interf_down $dev $WAN_CONF -+ fi -+ fi -+ done -+ -+ return 0 -+} -+ -+ - router_unconfig() - { - if [ $OSYSTEM != "Linux" ]; then -@@ -716,6 +933,7 @@ - # Unload WAN drivers. - } - -+ - #---------------------------------------------------------------------------- - # Remove character device /dev/wanrouter - #---------------------------------------------------------------------------- -@@ -908,9 +1126,9 @@ - { - for dev in $WAN_DEVICES; do - check_file "$WAN_CONF_DIR/$dev.conf" || { -- echo -e "\n$SCRIPT: Error, $WAN_CONF_DIR/$dev.conf not found!\n"; -- return 1; -- } -+ echo -e "\n$SCRIPT: Error, $WAN_CONF_DIR/$dev.conf not found!\n"; -+ return 1; -+ } - done - return 0; - } -@@ -968,27 +1186,6 @@ - return $rc - } - --function check_module () { -- -- if [ $OSYSTEM = "Linux" ]; then -- [ -d "$ROUTER_PROC" ] && { -- return 0 -- } -- else -- for i in $WAN_DRIVERS -- do $MODULE_STAT | grep -q $i && { -- return 0 -- } -- done -- fi -- # Driver is not loaded -- if [ $OSYSTEM != "Linux" ]; then -- rm -f $WAN_LOCK 2> /dev/null -- fi -- return 1; --} -- -- - function check_exists () { - - local device=$1 -@@ -1223,16 +1420,22 @@ - check_osystem () { - - if [ $OSYSTEM = "Linux" ]; then -- get_distrib -- if [ $? -eq 1 ]; then - -- if [ $WAN_LOCK != "/var/lock/subsys/wanrouter" ]; then -- echo -e "\nREDHAT Detected changing WAN_LOCK location" -- echo -e "to /var/lock/subsys/wanrouter" -- echo -e "To avoid this message change the WAN_LOCK directory" -- echo -e "in $WAN_CONF_DIR/wanrouter.rc to /var/lock/subsys/wanrouter\n" -- WAN_LOCK=/var/lock/subsys/wanrouter -- fi -+ if [ -d $WAN_LOCK_DIR ]; then -+ return 0 -+ else -+ echo -+ echo "Warning: WAN_LOCK_DIR = $WAN_LOCK_DIR does not exist!" -+ echo "Please update the WAN_LOCK_DIR in /etc/wanpipe/wanrouter.rc" -+ echo -+ fi -+ -+ if [ -d /var/lock/subsys ]; then -+ WAN_LOCK_DIR=/var/lock/subsys -+ elif [ -d /var/lock ]; then -+ WAN_LOCK_DIR=/var/lock -+ else -+ WAN_LOCK_DIR=$WAN_CONF_DIR - fi - fi - -@@ -1564,8 +1767,8 @@ - local err=0 - echo - -- if [ ! -d /etc/wanpipe ]; then -- echo "Error: /etc/wanpipe not found" -+ if [ ! -d ${WAN_HOME} ]; then -+ echo "Error: ${WAN_HOME} not found" - echo "Reason: Wanpipe not installed properly" - echo "Solution: Re-install wanpipe" - return -@@ -1587,7 +1790,7 @@ - unload_module - fi - -- if [ ! -f /etc/wanpipe/wanpipe1.conf ]; then -+ if [ ! -f ${WAN_HOME}/wanpipe1.conf ]; then - echo "Warning: wanpipe1.conf configuration file not found" - echo "Reason: did not run /usr/sbin/wancfg to create it" - echo "Solution: run /usr/sbin/wancfg :)" -@@ -1683,6 +1886,34 @@ - WAN_DEVICES= - } - -+function read_meta_conf () -+{ -+ -+ if [ $OSYSTEM = "Linux" ]; then -+ WAN_HOME=/etc/wanpipe -+ elif [ $OSYSTEM = "FreeBSD" -o $OSYSTEM = "OpenBSD" ]; then -+ WAN_HOME=/usr/local/etc/wanpipe -+ wanrouter_rc_file="" -+ if [ -r /etc/rc.conf ]; then -+ . /etc/rc.conf -+ fi -+ if [ -n "$wanrouter_rc_file" ]; then -+ WAN_HOME=${wanrouter_rc_file%/*} -+ fi -+ fi -+ WAN_CONF_DIR=$WAN_HOME -+ META_CONF=$WAN_HOME/wanrouter.rc -+ WAN_INTR_DIR=$WAN_HOME/interfaces -+ -+ # Read meta-configuration file. -+ if [ -f $META_CONF ] -+ then . $META_CONF -+ else -+ return 1 -+ fi -+ return 0 -+} -+ - function meta_conf_compatiblity () - { - WAN_CONF_DIR=$WANPIPE_CONF_DIR -@@ -1754,36 +1985,42 @@ - done - } - -+# FIXME: Add code for BSD - function wan_force_unload_modules() - { -- if [ -e "$ROUTER_PROC/status" ]; then -- wp_list=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort -r` -- if [ -z $list ]; then -- mod_list=`cat /proc/modules | grep wan | cut -d ' ' -f1 | xargs` -- for tmp_mod in $mod_list -- do -- eval "rmmod $tmp_mod >> /dev/null 2>> /dev/null" -- done -+ if [ $OSYSTEM = "Linux" ]; then -+ if [ -e "$ROUTER_PROC/status" ]; then -+ wp_list=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort -r` -+ if [ -z $list ]; then -+ mod_list=`cat /proc/modules | grep wan | cut -d ' ' -f1 | xargs` -+ for tmp_mod in $mod_list -+ do -+ eval "rmmod $tmp_mod >> /dev/null 2>> /dev/null" -+ done -+ fi - fi - fi - } - -+# FIXME: Add code for BSD - function stop_running_wanpipes () - { - -- if [ -e "$ROUTER_PROC/status" ]; then -- wp_list=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort -r` -- -- for list in $wp_list -- do -- list=${list// /}; -- if [ ! -z $list ]; then -- eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" -- wanrouter stop $list -- fi -- done -- -- wan_force_unload_modules -+ if [ $OSYSTEM = "Linux" ]; then -+ if [ -e "$ROUTER_PROC/status" ]; then -+ wp_list=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort -r` -+ -+ for list in $wp_list -+ do -+ list=${list// /}; -+ if [ ! -z $list ]; then -+ eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" -+ wanrouter stop $list -+ fi -+ done -+ -+ wan_force_unload_modules -+ fi - fi - } - -@@ -1861,10 +2098,6 @@ - OSYSTEM=`uname -s` - RELEASE=`uname -r` - PROD=wanpipe --WAN_HOME=/etc/wanpipe --WAN_CONF_DIR=$WAN_HOME --META_CONF=$WAN_HOME/wanrouter.rc --WAN_INTR_DIR=$WAN_HOME/interfaces - SCRIPT=wanrouter - REDHAT=/usr/src/redhat - ROUTER_PROC=/proc/net/wanrouter -@@ -1883,7 +2116,7 @@ - RUGGEDCOM=No - - if [ $OSYSTEM = "Linux" ]; then -- ROUTER_VERSION=3.1.4.1 -+ ROUTER_VERSION=beta1-2.3.5 - IFCONFIG_LIST=ifconfig - MODULE_STAT=lsmod - WAN_DRIVERS="wanpipe" -@@ -2042,14 +2275,11 @@ - trap '' 2 - - init_meta_conf -- --# Read meta-configuration file. --if [ -f $META_CONF ] --then . $META_CONF --else -+read_meta_conf -+if [ $? -ne 0 ]; then - echo "$SCRIPT: Error: $META_CONF not found!" - exit 1; --fi -+fi - - if [ "$WANPIPE_CONF_DIR" != "" -a "$WAN_CONF_DIR" = "" ] || [ "$WAN_ADSL_LIST" = "" ]; then - meta_conf_compatiblity -@@ -2073,6 +2303,10 @@ - - check_osystem - -+#Check osystem confirms the WAN_LOCK directory -+WAN_LOCK=$WAN_LOCK_DIR/wanrouter -+ -+ - if [ ! -f $WAN_ADSL_LIST ]; then - generate_adsl_list - fi -@@ -2131,12 +2365,12 @@ - fi - fi - --WAN_LOCK=$WAN_LOCK_DIR/wanrouter - - echo - # If modules doesn't loaded remove all lock file from WAN_LOCK_DIR. - check_module - -+ft1_or_wanpipe=0 - # See how we were called. - case "$1" in - start) -@@ -2151,49 +2385,9 @@ - cleanup 2 - fi - -- create_cdev -- -- for dev in $WAN_DEVICES; do -- if [ $OSYSTEM = "Linux" ] && [ ! -e "$ROUTER_PROC/$dev" ]; then -- echo -e "Error: Device $dev is not supported by kernel\n" -- continue -- fi -- WAN_CONF=$WAN_CONF_DIR/$dev.conf -- echo "Starting up device: $dev" -- echo "Starting up device: $dev" >> $WAN_LOG -- router_config $WAN_CONF $dev --#NC: Jul 22 2003 --#Just because one card --#fails to load do not stop --#other cards from loading --# if [ $? -ne 0 ]; then --# #echo "Exiting rc = 3" --# cleanup 3 --# fi -- done -- -- for dev in $WAN_DEVICES; do -- WAN_CONF=$WAN_CONF_DIR/$dev.conf -- interf_config $dev $WAN_CONF -- --#NC: Jul 22 2003 --#Just because one interface --#fails to load, do not stop all --#other interfaces. --# if [ $? -ne 0 ]; then --# cleanup 4 --# fi -- done -+ config_devices $WAN_DEVICES - -- for dev in $WAN_DEVICES; do -- WAN_CONF=$WAN_CONF_DIR/$dev.conf -- INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` -- for ifname in $INTERFACES; do -- ifname=${ifname%%=*} -- wanrouter_script start $dev $ifname -- done -- wanrouter_script start $dev -- done -+ config_interfaces $WAN_DEVICES - - wanrouter_script start - -@@ -2215,14 +2409,9 @@ - - check_file $WAN_CONF || cleanup 1 - -- check_module -+ load_module - if [ $? -ne 0 ]; then -- -- load_module -- if [ $? -ne 0 ]; then -- cleanup 2 -- fi -- create_cdev -+ cleanup 2 - fi - - #If we are starting FT1 driver, we have to check -@@ -2232,53 +2421,19 @@ - dev="wanpipe$ft1_or_wanpipe" - fi - -- check_exists $dev -- if [ $? -ne 0 ]; then -- echo "Error: Device $dev does not exist/not allocated." -- echo " Check the messages log for the number of probed " -- echo " devices." -- echo -- cleanup 1 -- fi -- -- check_dev_running $dev -- if [ $? -eq 0 ]; then -- echo "Error: Device $dev is already running" -- echo -e " Run 'wanrouter stop $dev' first\n" -- cleanup 1 -- fi -- -- #Since we changed the name of dev above, -- #we must check if we are running ft1 device, -- #output a correct message -- if [ $ft1_or_wanpipe -gt 0 ]; then -- echo "Starting up device: $dev, FT1 config mode" -- echo "Starting up device: $dev, FT1 config mode" >> $WAN_LOG -- else -- echo "Starting up device: $dev" -- echo "Starting up device: $dev" >> $WAN_LOG -- fi -- router_config $WAN_CONF $dev -+ config_devices $dev - if [ $? -ne 0 ]; then - cleanup 3 - fi -- -+ - #When loading ft1 device there are not interfaces - if [ $ft1_or_wanpipe -eq 0 ]; then -- interf_config $dev $WAN_CONF -+ config_interfaces $dev - if [ $? -ne 0 ]; then - cleanup 4 - fi - fi -- -- INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` -- for ifname in $INTERFACES; do -- ifname=${ifname%%=*} -- wanrouter_script start $dev $ifname -- done - -- wanrouter_script start $dev -- - else - #ROUTER START WANPIPE INTERFACE - -@@ -2301,9 +2456,9 @@ - - check_file $WAN_CONF || cleanup 1 - -- check_module -+ load_module - if [ $? -ne 0 ]; then -- load_module -+ cleanup 2 - fi - - eval "$IFCONFIG_LIST | grep -w $if_name > /dev/null 2> /dev/null" -@@ -2368,52 +2523,9 @@ - WAN_DEVICES=$tmp_dev_list - fi - -- #Stop all interfaces, but check whether -- #device is running first -- for dev in $WAN_DEVICES; do -- -- if [ "$dev" = "" ]; then -- continue; -- fi -- -- check_exists $dev -- if [ $? -eq 0 ]; then -- check_dev_running $dev -- if [ $? -eq 0 ]; then -- WAN_CONF=$WAN_CONF_DIR/$dev.conf -- interf_down $dev $WAN_CONF -- fi -- fi -- done -- -- #Stop all routers but check if device -- #is running first -- for dev in $WAN_DEVICES; do -- WAN_CONF=$WAN_CONF_DIR/$dev.conf -- echo "Shutting down device: $dev" -- echo "Shutting down device: $dev" >> $WAN_LOG -- router_unconfig $WAN_CONF $dev -- done -- -- #Check if any devices are still running -- # If YES: don't unload the modules, just printout -- # the list of active devices -- # If NO: unload modules -- check_and_print_still_running && cleanup 0 -- -- echo -e "No devices running, Unloading Modules" -- remove_cdev -- unload_module -+ unconfig_interfaces $WAN_DEVICES - -- for dev in $WAN_DEVICES; do -- WAN_CONF=$WAN_CONF_DIR/$dev.conf -- INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` -- for ifname in $INTERFACES; do -- ifname=${ifname%%=*} -- wanrouter_script stop $dev $ifname -- done -- wanrouter_script stop $dev -- done -+ unconfig_devices $WAN_DEVICES - - wanrouter_script stop - -@@ -2432,11 +2544,6 @@ - dev=$($GET_RC) - rm -f $RC - -- WAN_CONF=$WAN_CONF_DIR/$dev.conf -- -- #Check that all configuration files exist -- check_file $WAN_CONF || cleanup 1 -- - #Check that modules are up and running - check_module - if [ $? -ne 0 ]; then -@@ -2452,39 +2559,12 @@ - dev="wanpipe$ft1_or_wanpipe" - fi - -- #If we are starting ft1 device there are no -- #interfaces. -- if [ $ft1_or_wanpipe -gt 0 ]; then -- echo "Shutting down device: $dev, FT1 config mode" -- echo "Shutting down device: $dev, FT1 config mode" >> $WAN_LOG -- else -- interf_down $dev $WAN_CONF -- echo "Shutting down device: $dev" -- echo "Shutting down device: $dev" >> $WAN_LOG -+ if [ $ft1_or_wanpipe -eq 0 ]; then -+ unconfig_interfaces $dev - fi -- router_unconfig $WAN_CONF $dev - -+ unconfig_devices $dev - -- #Check if any devices are still running -- # If YES: don't unload the modules, just printout -- # the list of active devices -- # If NO: unload modules -- -- check_and_print_still_running && cleanup 0 -- -- cd $WAN_HOME -- echo -e "No devices running, Unloading Modules" -- remove_cdev -- unload_module -- -- INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` -- for ifname in $INTERFACES; do -- ifname=${ifname%%=*} -- wanrouter_script stop $dev $ifname -- done -- -- wanrouter_script stop $dev -- - [ -f $WAN_CONF_DIR/$FT1_CONF ] && rm -f $WAN_CONF_DIR/$FT1_CONF - - else -@@ -2533,6 +2613,121 @@ - fi - ;; - -+ start_dev) -+ -+ if [ -z $2 ]; then -+ # WANROUTER START_DEV -+ -+ check_config || cleanup 1 -+ -+ load_module -+ if [ $? -ne 0 ]; then -+ cleanup 2 -+ fi -+ -+ config_devices $WAN_DEVICES -+ -+ elif [ -z $3 ]; then -+ #ROUTER START_DEV WANPIPE -+ -+ dev=$2 -+ -+ load_module -+ if [ $? -ne 0 ]; then -+ cleanup 2 -+ fi -+ -+ config_devices $dev -+ if [ $? -ne 0 ]; then -+ cleanup 3 -+ fi -+ fi -+ ;; -+ -+ stop_dev) -+ -+ if [ -z $2 ]; then -+ #WANROUTER STOP_DEV -+ -+ check_module -+ if [ $? -ne 0 ]; then -+ unload_module -+ remove_cdev -+ echo -e "Router is already stopped !\n" -+ cleanup 1 -+ fi -+ -+ #Check that all wanpipe#.conf file defined in -+ # WAN_DEVICES exist -+ check_config || { -+ unload_module -+ remove_cdev -+ echo -e "No devices running, Unloading Modules" -+ cleanup 1 -+ } -+ -+ if [ "$WAN_DEVICES_REV_STOP_ORDER" = "YES" ]; then -+ tmp_dev_list= -+ for dev in $WAN_DEVICES; do -+ tmp_dev_list="$dev ""$tmp_dev_list" -+ done -+ WAN_DEVICES=$tmp_dev_list -+ fi -+ -+ unconfig_devices $WAN_DEVICES -+ -+ wanrouter_script stop -+ -+ elif [ -z $3 ]; then -+ #WANROUTER STOP_DEV WANPIPE -+ -+ dev=$2 -+ -+ if [ "$dev" = "all" ]; then -+ stop_running_wanpipes -+ cleanup 0 -+ fi -+ -+ #Check that modules are up and running -+ check_module -+ if [ $? -ne 0 ]; then -+ unload_module -+ echo -e "Router is already stopped !\n"; -+ cleanup 1; -+ fi -+ -+ unconfig_devices $dev -+ fi -+ ;; -+ -+ start_ip) -+ -+ if [ -z $2 ]; then -+ # WANROUTER START_IP -+ check_config || cleanup 1 -+ -+ config_interfaces $WAN_DEVICES -+ -+ wanrouter_script start -+ -+ elif [ -z $3 ]; then -+ #ROUTER START_IP WANPIPE -+ config_interfaces $2 -+ fi -+ ;; -+ -+ stop_ip) -+ -+ if [ -z $2 ]; then -+ #WANROUTER STOP_IP -+ unconfig_interfaces $WAN_DEVICES -+ -+ elif [ -z $3 ]; then -+ #WANROUTER STOP_IP WANPIPE -+ unconfig_interfaces $2 -+ fi -+ ;; -+ - script) - - #Debug Statement, used to test the script option -@@ -2576,6 +2771,31 @@ - fi - cleanup 0; - ;; -+ -+ restart_dev) -+ eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" -+ if [ "$2" = "" ]; then -+ $0 stop_dev; -+ $0 start_dev; -+ elif [ "$3" = "" ]; then -+ $0 stop_dev $2; -+ $0 start_dev $2; -+ fi -+ cleanup 0; -+ ;; -+ -+ restart_ip) -+ eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" -+ if [ "$2" = "" ]; then -+ $0 stop_ip; -+ $0 start_ip; -+ elif [ "$3" = "" ]; then -+ $0 stop_ip $2; -+ $0 start_ip $2; -+ fi -+ cleanup 0; -+ ;; -+ - modules) - - if [ $OSYSTEM = "Linux" ]; then -@@ -2618,14 +2838,12 @@ - if [ $OSYSTEM = "Linux" ]; then - cat /proc/net/wanrouter/hwprobe_verbose - else -- create_cdev - wanconfig hwprobe verbose - fi - else - if [ $OSYSTEM = "Linux" ]; then - cat /proc/net/wanrouter/hwprobe - else -- create_cdev - wanconfig hwprobe - fi - fi -@@ -2708,21 +2926,22 @@ - echo -e " wanrouter start : Starts all devices specified in" - echo -e " $WAN_CONF_DIR/wanrouter.rc WAN_DEVICES\n" - echo -e " wanrouter stop : Stops all devices specified in" -- echo -e " $WAN_CONF_DIR/wanrouter.rc WAN_DEVICES\n" -- -+ echo -e " $WAN_CONF_DIR/wanrouter.rc WAN_DEVICES\n" - echo -e " wanrouter start wanpipe# : Start a single device\n" - echo -e " wanrouter stop wanpipe# : Stops a single device" - echo -e " (# can range from 1 to 16)\n" -+ if [ $OSYSTEM = "Linux" ]; then -+ echo -e " wanrouter start wanpipe# if_name : Start a single interface on device\n" -+ echo -e " wanrouter stop wanpipe# if_name : Stops a single interface on device" -+ echo -e " (# can range from 1 to 16)\n" -+ -+ fi - echo -e " wanrouter restart : Restart all devices specified in" - echo -e " $WAN_CONF_DIR/wanrouter.rc WAN_DEVICES\n" - echo -e " wanrouter restart wanpipe# : Restart a single device" - echo -e " (# can range from 1 to 16)\n" - echo - if [ $OSYSTEM = "Linux" ]; then -- echo -e " wanrouter start wanpipe# if_name : Start a single interface on device\n" -- echo -e " wanrouter stop wanpipe# if_name : Stops a single interface on device" -- echo -e " (# can range from 1 to 16)\n" -- - echo -e " wanrouter restart wanpipe# if_name : Restart a single interface on device" - echo -e " (# can range from 1 to 16)\n" - echo diff --git a/samples/wanrouter b/samples/wanrouter index 1f02e8f..5f244d6 100644 --- a/samples/wanrouter +++ b/samples/wanrouter @@ -1,6 +1,6 @@ #!/bin/bash -p # chkconfig: 2345 7 9 -# wanrouter WANPIPE WAN Router Initialization Script. +# description: Starts and stop Wanpipe devices # # copyright (c) 1999-2002, Sangoma Technologies Inc. # @@ -730,6 +730,7 @@ interf_down() for i in $INTERFACES do int_file=${i%%=*} + wanrouter_script stop $device $int_file #excutes interface stop script echo "Shutting down $device interface: $int_file" ifconfig $int_file down done @@ -807,6 +808,7 @@ unconfig_devices() #If we are starting ft1 device there are no #interfaces. + wanrouter_script stop $dev if [ $ft1_or_wanpipe -gt 0 ]; then echo "Shutting down device: $dev, FT1 config mode" echo "Shutting down device: $dev, FT1 config mode" >> $WAN_LOG @@ -830,18 +832,6 @@ unconfig_devices() remove_cdev unload_module - for dev in $devices; do - WAN_CONF=$WAN_CONF_DIR/$dev.conf - - INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` - for ifname in $INTERFACES; do - ifname=${ifname%%=*} - wanrouter_script stop $dev $ifname - done - wanrouter_script stop $dev - - done - return 0 } @@ -2116,7 +2106,7 @@ WANPIPE_IS_RUNNING=/var/run/wanpipe_is_running RUGGEDCOM=No if [ $OSYSTEM = "Linux" ]; then - ROUTER_VERSION=3.2.1 + ROUTER_VERSION=3.2.2 IFCONFIG_LIST=ifconfig MODULE_STAT=lsmod WAN_DRIVERS="wanpipe" @@ -2523,11 +2513,12 @@ case "$1" in WAN_DEVICES=$tmp_dev_list fi + wanrouter_script stop + unconfig_interfaces $WAN_DEVICES unconfig_devices $WAN_DEVICES - wanrouter_script stop elif [ -z $3 ]; then #WANROUTER STOP WANPIPE @@ -2586,6 +2577,8 @@ case "$1" in WAN_CONF=$WAN_CONF_DIR/$dev.conf check_file $WAN_CONF || cleanup 1 + + wanrouter_script stop $dev $if_name eval "$IFCONFIG_LIST | grep -w $if_name > /dev/null 2> /dev/null" if [ $? -eq 0 ]; then @@ -2609,7 +2602,6 @@ case "$1" in echo -e "No devices running, Unloading Modules" unload_module - wanrouter_script stop $dev $if_name fi ;; diff --git a/samples/wanrouter.org b/samples/wanrouter.org new file mode 100644 index 0000000..1f02e8f --- /dev/null +++ b/samples/wanrouter.org @@ -0,0 +1,2986 @@ +#!/bin/bash -p +# chkconfig: 2345 7 9 +# wanrouter WANPIPE WAN Router Initialization Script. +# +# copyright (c) 1999-2002, Sangoma Technologies Inc. +# +# 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. +# ============================================================================ +# July 28,2004 Alex Feldman Do not run 'ztcfg' after interface +# configuration. Run ztcfg script manually +# after all Voip interfaces loaded. +# Jan 16, 2004 David Rokhvarg Added 'lineprobe' option +# Mar 12, 2001 Nenad Corbic Added new if support +# Feb 20, 2001 Nenad Corbic Use /proc/net/wanrouter/status to determine +# the active devices. +# Jul 17, 2000 Nenad Corbic Added version option. +# Fixed the shutdown bug. If all interfaces +# are down but modules loaded, unload +# modules. +# May 30, 2000 Nenad Corbic Updated for v2.1.4 +# Enable IP Forwarding Option +# Apr 05, 2000 Nenad Corbic Updated for v2.1.3 +# Feb 22. 2000 Nenad Corbic Updated for v2.1.2 +# Feb 15, 2000 Nenad Corbic Load WANPIPE socket module along +# with router modules. +# Jan 18, 2000 Nenad Corbic No interface files are needed for API, +# interfaces. No IP addresses neccessary. +# Nov 09, 1999 Nenad Corbic Updated for v2.1.1 +# Enabled starting and stoping +# each wanpipe device separately. +# Nov 09, 1999 Nenad Corbic Updated for v2.1.1 +# Oct 04, 1999 Nenad Corbic Updated for v2.1.0 +# Aug 04, 1999 Nenad Corbic Updated for v2.0.5 +# Oct 15, 1998 Jaspreet Singh Updated for v2.0.4 +# Dec 09, 1997 Jaspreet Singh Updated for v2.0.2 +# Nov 28, 1997 Jaspreet Singh Updated for v2.0.1 +# Nov 06, 1997 Jaspreet Singh Updated for v2.0.0 +# Jul 28, 1997 Jaspreet Singh Updated for v1.0.5 +# Jul 10, 1997 Jaspreet Singh Updated for v1.0.4 +# Dec 15, 1996 Gene Kozin Initial version based on Sangoma's WANPIPE(tm) +# ============================================================================ + +####### FUNCTION DEFINITIONS ################################################# + + +# ---------------------------------------------------------------------------- +# Prompt user for input. +# ---------------------------------------------------------------------------- +prompt() +{ + if test $NONINTERACTIVE; then + return 0 + fi + + echo -ne "$*" >&2 + read CMD rest + return 0 +} + +# ---------------------------------------------------------------------------- +# Get Yes/No +# ---------------------------------------------------------------------------- +getyn() +{ + if test $NONINTERACTIVE; then + return 0 + fi + + while prompt "$* (y/n) " + do case $CMD in + [yY]) return 0 + ;; + [nN]) return 1 + ;; + *) echo -e "\nPlease answer y or n" >&2 + ;; + esac + done +} + +# ---------------------------------------------------------------------------- +# Pause. +# ---------------------------------------------------------------------------- +pause() +{ + + [ $# -ne 0 ] && echo -e $* >&2 + echo -e "Press [Enter] to continue...\c" >&2 + read tmp + return 0 +} + +check_bash () +{ + BASH_SUPPORT=`echo $BASH_VERSION | cut -d'.' -f1 2> /dev/null` +} + +check_awk () +{ + major_ver=${RELEASE%%.*} + if [ $OSYSTEM = "Linux" ]; then + eval "type awk 2> /dev/null > /dev/null" + elif [ $OSYSTEM = "FreeBSD" -a "$major_ver" = "5" ]; then + eval "type awk 2> /dev/null > /dev/null" + elif [ $OSYSTEM = "FreeBSD" -a "$major_ver" = "6" ]; then + eval "type awk 2> /dev/null > /dev/null" + else + eval "awk 2> /dev/null > /dev/null" + fi + if [ $? -eq 0 ]; then + AWK_SUPPORT=YES + else + AWK_SUPPORT=NO + fi +} + +function cleanup () +{ + eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" + + #Check module checks if modules are loaded and updates + #the subsys lock for LINUX + check_module + + exit $1 +} + + +# ---------------------------------------------------------------------------- +# Check to see if a value belongs to the list. +# Return: 0 - yes +# 1 - no +# ---------------------------------------------------------------------------- +check_list() +{ + [ $# -lt 2 ] && return 1 + + val=$1 + shift + for i in $* + do [ "$val" = "$i" ] && return 0 + done + return 1 +} + +# ---------------------------------------------------------------------------- +# Display error message. +# ---------------------------------------------------------------------------- +error() { + echo -e "$SCRIPT: $*!" + [ -f "$WAN_LOG" ] && echo -e "$*!" >> $WAN_LOG + return 0 +} + +file_exist() { + local ret + eval "ls $1.* > /dev/null 2> /dev/null" + ret=$? + return $ret +} + +# ---------------------------------------------------------------------------- +# Configure network interface. +# This routine performs TCP/IP-level interface configuration. Interface name +# is given as an argument. It reads a configuration file with the same name in +# and calls ifconfig and route to do the job. +# +# Configuration file is actually a shell script containing only variables: +# +# ONBOOT=yes if not 'yes' then skip this file +# IPADDR=xxx.xxx.xxx.xxx IP address of this interface +# NETMASK=xxx.xxx.xxx.xxx Network mask for this interface +# NETWORK=xxx.xxx.xxx.xxx Network address +# BROADCAST=xxx.xxx.xxx.xxx Broadcast address +# POINTOPOINT=xxx.xxx.xxx.xxx Point-to-point address +# GATEWAY=xxx.xxx.xxx.xxx Gateway address +# ---------------------------------------------------------------------------- +interface_up() +{ + ONBOOT= + IPADDR= + NETMASK= + NETWORK= + BROADCAST= + POINTOPOINT= + GATEWAY= + + if [ $NEW_IF_TYPE = YES ]; then + if [ $LINUX_DISTR = redhat ]; then + if [ $WAN_INTR_DIR = "/etc/sysconfig/network-scripts" ]; then + ifup $1 + return 0 + fi + fi + source $WAN_INTR_DIR/ifcfg-$1 + else + if [ ! -f $WAN_INTR_DIR/$1 ]; then + ifconfig $1 up + return 0; + fi + + source $WAN_INTR_DIR/$1 + fi + + + # Configure interface. + if [ "$IPADDR" -a "$IPADDR" != "0.0.0.0" ]; then + # Prepare ifconfig options. + OPTIONS= + if [ $OSYSTEM = "Linux" ]; then + [ "$POINTOPOINT" ] && OPTIONS="$OPTIONS pointopoint $POINTOPOINT" + else + [ "$POINTOPOINT" ] && OPTIONS="$OPTIONS $POINTOPOINT" + fi + [ "$NETMASK" ] && OPTIONS="$OPTIONS netmask $NETMASK" + [ "$BROADCAST" ] && OPTIONS="$OPTIONS broadcast $BROADCAST" + + if [ $OSYSTEM = "Linux" ]; then + ifconfig $1 $IPADDR $OPTIONS + else + ifconfig $1 inet $IPADDR $OPTIONS + fi + ifconfig $1 up + else + ifconfig $1 up + fi + + if [ "$GATEWAY" ]; then + check_command_exist route + if [ $? -eq 0 ]; then + if [ $OSYSTEM = "Linux" ]; then + if [ "$GATEWAY" = 0 ] || [ "$GATEWAY" = "0.0.0.0" ]; then + if [ "$IPADDR" -a "$IPADDR" != "0" -a "$IPADDR" != "0.0.0.0" ]; then + route add default dev $1 + fi + else + route add default gw $GATEWAY + fi + else + if [ "$GATEWAY" = 0 ] || [ "$GATEWAY" = "0.0.0.0" ]; then + if [ "$IPADDR" -a "$IPADDR" != "0" -a "$IPADDR" != "0.0.0.0" ]; then + route add -net 0.0.0.0 -interface $1 + fi + else + route add -net 0.0.0.0 $GATEWAY + fi + fi + else + if [ $OSYSTEM = "Linux" ]; then + check_command_exist ip + if [ $? -eq 0 ]; then + if [ "$GATEWAY" = 0 ] || [ "$GATEWAY" = "0.0.0.0" ]; then + ip route add default dev $1 + else + ip route add default via $GATEWAY + fi + return 0 + fi + fi + echo + echo "Error: Failed to set route, no route or ip cmd found" + echo + fi + fi + + if [ $OSYSTEM = "Linux" ] && [ $LINUX_DISTR = redhat ]; then + /etc/sysconfig/network-scripts/ifup-routes $1 + fi + + + return 0 +} + +function check_module () { + + if [ $OSYSTEM = "Linux" ]; then + [ -d "$ROUTER_PROC" ] && { + touch $WAN_LOCK 2> /dev/null + return 0 + } + else + for i in $WAN_DRIVERS + do $MODULE_STAT | grep -q $i && { + touch $WAN_LOCK 2> /dev/null + return 0 + } + done + fi + + # Driver is not loaded + if [ -e $WAN_LOCK ]; then + rm -f $WAN_LOCK 2> /dev/null + fi + return 1; +} + +function load_driver () { + + local err + + if [ $OSYSTEM = "Linux" ]; then + $MODULE_LOAD $1 > /dev/null + err=$? + elif [ $OSYSTEM = "FreeBSD" ]; then + err=`$MODULE_LOAD $1 >/dev/null` + elif [ $OSYSTEM = "OpenBSD" -o $OSYSTEM = "NetBSD" ]; then + err=`$MODULE_LOAD -o $MODULE_DIR/$1.out -e$1 -p$MODULE_DIR/$POSTINSTALL $MODULE_DIR/$1.o 1> /dev/null` + fi + return $err +} + +function unload_driver () { + + local err + + if [ $OSYSTEM = "OpenBSD" -o $OSYSTEM = "NetBSD" ]; then + \rm -rf $MODULE_DIR/$1.out + err=`$MODULE_UNLOAD -n $1 2> /dev/null` + else + err=`$MODULE_UNLOAD $1 2> /dev/null` + err=`$MODULE_UNLOAD sdladrv 2> /dev/null` + fi + + +#Deprecated: Confirm Alex +#FIXME +# if [ $OSYSTEM = "Linux" ]; then +# # try to unload Echo Canceller module +# eval "wan_ec_client unload 2>/dev/null" +# fi + + return $err +} + +#-------------------------------------------------------------------------- +# Create character device /dev/wanrouter +#-------------------------------------------------------------------------- +create_cdev() +{ + if [ $OSYSTEM = "FreeBSD" ]; then + [ ! -e "$CDEV_WANROUTER" ] && { + mknod $CDEV_WANROUTER c $CDEV_MAJOR $CDEV_MINOR + } + fi +} + + +# ---------------------------------------------------------------------------- +# Start WAN wanrouter. +# o create log file +# o check configuration file presence +# o load WAN drivers (using modprobe) +# o configure drivers +# o configure interfaces +# ---------------------------------------------------------------------------- +load_module() +{ + local opt=${1:-NO} + + check_module + if [ $? -eq 0 ]; then + return 0 + fi + + if [ $opt != silent ]; then + echo "Starting WAN Router..." + echo "`date`: starting WAN router" >> $WAN_LOG + fi + + if [ $OSYSTEM = "Linux" ]; then + if [ -e "/proc/net/wanrouter" ]; then + + #Make sure to load optionl modules + wansock_config LOAD + annexg_config LOAD + lip_config LOAD + wanec_config LOAD + + #RuggedCom LedTask + touch $WANPIPE_IS_RUNNING + return 0 + fi + fi + + # Check if SecureLevel allows to load module. + if [ $OSYSTEM = "OpenBSD" ]; then + if [ $SECURELEVEL -gt 0 ]; then +echo "Error: Your securelevel does not allow to load kernel modules!" + return 1 + fi + fi + + for i in $MODULES + do + + module_name=$i${MODULE_EXT} + if [ ! -f $module_name ]; then + if [ $OSYSTEM = "Linux" ]; then + eval "echo $OPT_MODULES | grep $i > /dev/null 2> /dev/null" + if [ $? -ne 0 ]; then + mod_error $i + return 1 + fi + else + mod_error $i + return 1 + fi + fi + done + + [ "$ROUTER_BOOT" = "NO" -o -z "$WAN_DRIVERS" ] && { + + echo -e "\n\nERROR in $WAN_CONF_DIR/wanrouter.rc file !!!" + echo -e " ROUTER_BOOT is set to NO, OR" + echo -e " WAN_DRIVERS must be set to wanpipe\n" + echo -e " wanrouter start failed !!!\n" + return 1 + } + + if [ $DEPMOD = YES ]; then + if [ $opt != silent ]; then + echo -n "Loading WAN drivers: " + fi + for i in $WAN_DRIVERS + do + $MODULE_STAT | grep -q $i && continue + + if [ $opt != silent ]; then + echo -n "$i " + echo -n "Loading driver $i ... " >> $WAN_LOG + fi + + if load_driver $i + then + echo "ok" >> $WAN_LOG + else + if [ $opt != silent ]; then + echo -e "\nFailed to load wanpipe modules !\n" + echo "fail" >> $WAN_LOG + fi + unload_module + return 1 + fi + done + else + if [ $opt != silent ]; then + echo -n "Loading WAN drivers: " + fi + + for i in $MODULES + do + if load_driver "$i" + then + if [ $opt != silent ]; then + echo "ok" >> $WAN_LOG + fi + else + if [ $opt != silent ]; then + echo -e "\nFailed to load wanpipe modules !\n" + echo "fail" >> $WAN_LOG + fi + unload_module + return 1 + fi + done + fi + + if [ $OSYSTEM = "Linux" ]; then + wansock_config LOAD + annexg_config LOAD + fi + + if ! lip_config LOAD + then + unload_module + return 1 + fi + + if ! wanec_config LOAD + then + lip_config UNLOAD + unload_module + return 1 + fi + + if [ $opt != silent ]; then + echo "done." + fi + + # Create char devices (if needed) + create_cdev + + touch $WANPIPE_IS_RUNNING + return 0 +} + +router_config() +{ + # Configure router. + if [ $OSYSTEM != "Linux" ]; then + [ -e "$CDEV_WANROUTER" ] || { + return 1 + } + fi + + # $1 = /etc/wanpipe#.conf where # is an integer + if [ "$WAN_DYN_WANCONFIG" = YES ]; then + eval "/usr/sbin/wanconfig_client cmd=start,card=$2" + else + wanconfig -v -f $1 -a $WAN_ADSL_LIST >> $WAN_LOG + fi +} + +interf_config() +{ + local device=$1 + local WAN_CONF=$2 + local int_file + local INTERFACES + local voip_flag + + + #echo "============ iterf_config ================" + + # Configure network interfaces. + if [ ! -d "$WAN_INTR_DIR" ]; then + error "Directory $WAN_INTR_DIR not found" + return 1 + fi + + #If TTY is defined there are no network interfaces + eval "grep \"TTY.*=.*YES\" -i $WAN_CONF > /dev/null" + if [ $? -eq 0 ]; then + echo -e "done." + return 0 + fi + + #eval "grep \"WAN_EDU_KIT\" -i $WAN_CONF > /dev/null" + #if [ $? -eq 0 ]; then + # echo -e "done." + # return 0 + #fi + + eval "grep \"WAN_DEBUG\" -i $WAN_CONF > /dev/null" + if [ $? -eq 0 ]; then + echo -e "done." + return 0 + fi + + eval "grep \"WAN_MLINK_PPP\" -i $WAN_CONF > /dev/null" + if [ $? -eq 0 ]; then + echo -e "done." + return 0 + fi + +#NC: Used to be when we used PPPD but now we +# use syncppp for PPPOA. This is just legacy +# the code should be deleted once we are sure +# we will never go back to tty model +# eval "grep \"WAN_ADSL\" -i $WAN_CONF > /dev/null" +# if [ $? -eq 0 ]; then +# eval "grep \"PPP_.*_OA\" -i $WAN_CONF > /dev/null" +# if [ $? -eq 0 ]; then +# echo -e "done." +# return 0 +# fi +# fi + + cd $WAN_INTR_DIR + +# if [ -f $WAN_INTERFACE_PROC_FILE ]; then +# INTERFACES=`cat $WAN_INTERFACE_PROC_FILE | grep $device | cut -d' ' -f1` +# else + INTERFACES=`grep ".*=.*$device" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` +# fi + + INTERFACES=${INTERFACES// /} + + + if [ -z "$INTERFACES" ]; then + error "No interface definitions found in $WAN_CONF" + return 1 + fi + + echo -n "Configuring interfaces: " + for i in $INTERFACES + do + int_file=${i%%=*} + + #Not every system has egrep. Egrep uses the regular expression matching. + + check_command_exist egrep + if [ $? -eq 0 ]; then + API=`egrep "$int_file[[:space:]]*=" -i $WAN_CONF | cut -d',' -f3 2> /dev/null` + else + API=`grep "$int_file =" -i $WAN_CONF | cut -d',' -f3 2> /dev/null` + fi + + #If the card is in backup mode, it will be used to monitor + #the primary link. We don't want IP information, thus + #we set the API field. This will cause the interface to + #come up without IP information. + eval "grep \"BACKUP.*=.*YES\" -i $WAN_CONF > /dev/null" + if [ $? -eq 0 ]; then + API=API + fi + + #Substitution and replacement are no supported + #on bash versions lower than 2.0 + + #if the card is configured as API, bring up all + #interfaces without IP information. + + if [ ! -z $API ]; then + + #Remove all white spaces + if [ "$AWK_SUPPORT" = YES ]; then + API=`echo $API | awk '{ gsub(" ", "") ; print }'` + elif [ "$BASH_SUPPORT" -gt 1 ]; then + API=${API// /} + fi + + if [ "$API" = API ] || [ "$API" = TDM_API ] || [ "$API" = TDM_VOICE_API ]; then + echo -n "$int_file " + ifconfig $int_file up + continue + fi + + + + if [ "$API" = TTY ]; then + continue + fi + + #brings up (for example wp1_fr16 and wp1_fr16e) + #with IP addresses 0.0.0.0 + if [ $API = "BRIDGE" ];then + + # Bring up BRIDGE interface + echo -n "$int_file " + ifconfig $int_file up + continue + fi + + if [ $API = "TRUNK" ];then + + # Bring up Trunk interface + echo -n "$int_file " + ifconfig $int_file up + continue + fi + + if [ $API = "SWITCH" ];then + + # Bring up SWITCH interface + echo -n "$int_file " + ifconfig $int_file up + continue + fi + + if [ $API = "ANNEXG" ];then + + # Bring up SWITCH interface + echo -n "$int_file " + ifconfig $int_file up + continue + fi + + if [ $API = "VoIP" ] || [ $API = "TDM_VOICE" ] || [ $API = "TDM_VOICE_API" ] ;then + + # Bring up VoIP interface + echo -n "$int_file " + ifconfig $int_file up + voip_flag=1 + continue + fi + + if [ $API = "PPPoE" ] || [ $API = "STACK" ];then + + # Bring up SWITCH interface + echo -n "$int_file " + ifconfig $int_file up + continue + fi + + fi + if [ $NEW_IF_TYPE = YES ]; then + if_file=ifcfg-$int_file; + else + if_file=$int_file; + fi + + if [ -s $if_file ]; then + echo -n "$int_file " + interface_up $int_file || { + error "Failed to configure interface $int_file" + continue + } + else + echo "Error Interface File $int_file not found" + return 1; + fi + + done + echo -e "\ndone." + + return 0 +} + +# ---------------------------------------------------------------------------- +# Stop WAN router. +# o shut down interfaces +# o unload WAN drivers +# o remove lock file +# ---------------------------------------------------------------------------- +interf_down() +{ + local device=$1 + local WAN_CONF=$2 + local int_file + local INTERFACES + + # Shut down network interfaces. + [ -d "$WAN_INTR_DIR" ] && { + cd $WAN_INTR_DIR + INTERFACES=`grep ".*=.*$device" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` + for i in $INTERFACES + do + int_file=${i%%=*} + echo "Shutting down $device interface: $int_file" + ifconfig $int_file down + done + } +} + +# ---------------------------------------------------------------------------- +# Configure devices (all or single). +# ---------------------------------------------------------------------------- +config_devices() +{ + local devices=$* + + for dev in $devices; do + if [ $OSYSTEM = "Linux" ] && [ ! -e "$ROUTER_PROC/$dev" ]; then + echo -e "Error: Device $dev is not supported by kernel\n" + continue + fi + WAN_CONF=$WAN_CONF_DIR/$dev.conf + + check_file $WAN_CONF || cleanup 1 + + check_exists $dev + if [ $? -ne 0 ]; then + echo "Error: Device $dev does not exist/not allocated." + echo " Check the messages log for the number of probed " + echo " devices." + echo + continue + fi + + check_dev_running $dev + if [ $? -eq 0 ]; then + echo "Error: Device $dev is already running" + echo -e " Run 'wanrouter stop $dev' first\n" + continue + fi + + #Since we changed the name of dev above, + #we must check if we are running ft1 device, + #output a correct message + if [ $ft1_or_wanpipe -gt 0 ]; then + echo "Starting up device: $dev, FT1 config mode" + echo "Starting up device: $dev, FT1 config mode" >> $WAN_LOG + else + echo "Starting up device: $dev" + echo "Starting up device: $dev" >> $WAN_LOG + fi + + router_config $WAN_CONF $dev +#NC: Jul 22 2003 +#Just because one card +#fails to load do not stop +#other cards from loading +# if [ $? -ne 0 ]; then +# #echo "Exiting rc = 3" +# cleanup 3 +# fi + done + + return 0 +} + +# ---------------------------------------------------------------------------- +# Unconfigure devices (all or single). +# ---------------------------------------------------------------------------- +unconfig_devices() +{ + local devices=$* + + #Stop all routers but check if device + #is running first + for dev in $devices; do + WAN_CONF=$WAN_CONF_DIR/$dev.conf + + #If we are starting ft1 device there are no + #interfaces. + if [ $ft1_or_wanpipe -gt 0 ]; then + echo "Shutting down device: $dev, FT1 config mode" + echo "Shutting down device: $dev, FT1 config mode" >> $WAN_LOG + else + echo "Shutting down device: $dev" + echo "Shutting down device: $dev" >> $WAN_LOG + fi + router_unconfig $WAN_CONF $dev + + done + + #Check if any devices are still running + # If YES: don't unload the modules, just printout + # the list of active devices + # If NO: unload modules + + check_and_print_still_running && cleanup 0 + + cd $WAN_HOME + echo -e "No devices running, Unloading Modules" + remove_cdev + unload_module + + for dev in $devices; do + WAN_CONF=$WAN_CONF_DIR/$dev.conf + + INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` + for ifname in $INTERFACES; do + ifname=${ifname%%=*} + wanrouter_script stop $dev $ifname + done + wanrouter_script stop $dev + + done + + return 0 +} + +# ---------------------------------------------------------------------------- +# Configure wan interfaces (all or single). +# ---------------------------------------------------------------------------- +config_interfaces() +{ + local devices=$* + + for dev in $devices; do + + WAN_CONF=$WAN_CONF_DIR/$dev.conf + + check_file $WAN_CONF || cleanup 1 + + interf_config $dev $WAN_CONF + +#NC: Jul 22 2003 +#Just because one interface +#fails to load, do not stop all +#other interfaces. +# if [ $? -ne 0 ]; then +# cleanup 4 +# fi + done + + for dev in $devices; do + WAN_CONF=$WAN_CONF_DIR/$dev.conf + INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` + for ifname in $INTERFACES; do + ifname=${ifname%%=*} + wanrouter_script start $dev $ifname + done + wanrouter_script start $dev + done + + return 0 +} + +# ---------------------------------------------------------------------------- +# unconfigure interface (all or single). +# ---------------------------------------------------------------------------- +unconfig_interfaces() +{ + local devices=$* + + #Stop all interfaces, but check whether + #device is running first + for dev in $devices; do + + if [ "$dev" = "" ]; then + continue; + fi + + WAN_CONF=$WAN_CONF_DIR/$dev.conf + + #Check that all configuration files exist + check_file $WAN_CONF || cleanup 1 + + check_exists $dev + if [ $? -eq 0 ]; then + check_dev_running $dev + if [ $? -eq 0 ]; then + WAN_CONF=$WAN_CONF_DIR/$dev.conf + interf_down $dev $WAN_CONF + fi + fi + done + + return 0 +} + + +router_unconfig() +{ + if [ $OSYSTEM != "Linux" ]; then + [ -e "$CDEV_WANROUTER" ] || { + return + } + fi + + + if [ "$WAN_DYN_WANCONFIG" = YES ]; then + eval "/usr/sbin/wanconfig_client cmd=stop,card=$2" + else + wanconfig -v -d $1 -a $WAN_ADSL_LIST >> $WAN_LOG + fi + # Unload WAN drivers. +} + + +#---------------------------------------------------------------------------- +# Remove character device /dev/wanrouter +#---------------------------------------------------------------------------- +remove_cdev() +{ + if [ $OSYSTEM = "FreeBSD" ]; then + [ -e "$CDEV_WANROUTER" ] && { + rm $CDEV_WANROUTER + } + fi +} + +unload_module() +{ + cd $WAN_HOME + + rm -f $WANPIPE_IS_RUNNING + if [ $RUGGEDCOM = "Yes" ]; then + sleep 2 + if lsof | grep '/proc/net/wanrouter' -q; then + echo "/proc/net/wanrouter still busy! Failed to make ledtask release..." + touch $WANPIPE_IS_RUNNING + return 0 + fi + fi + + if [ $OSYSTEM = "Linux" ]; then + check_and_print_still_running && cleanup 1 + wansock_config UNLOAD + annexg_config UNLOAD + elif [ $OSYSTEM = "OpenBSD" ]; then + if [ $SECURELEVEL -gt 0 ]; then +echo "Error: Your securelevel does not allow to load kernel modules!" + return 1 + fi + fi + + wanec_config UNLOAD + lip_config UNLOAD + + if [ $DEPMOD = YES ]; then + + for i in $WAN_DRIVERS + do $MODULE_STAT | grep -q $i && { + unload_driver $i + } + done + + else + for i in $UMODULES + do + unload_driver $i + done + fi + + wan_force_unload_modules +} + + +wanec_config () +{ + local opt=$1 + + if [ "$WANEC_LOAD" != "YES" ]; then + return 0 + fi + + if [ $OSYSTEM != "FreeBSD" -a $OSYSTEM != "Linux" ]; then + return 0 + fi + + file_exist $MOD10 + if [ $? -ne 0 ]; then + return 0 + fi + + if [ $DEPMOD != YES ]; then + return 0 + fi + + if [ $opt = UNLOAD ]; then + lsmods=`$MODULE_STAT` + + for i in $WANEC_UNLOAD_DRIVERS + do + echo "$lsmods" | grep -q "$i" && { + if ! unload_driver $i + then + return 1 + fi + } + done + else + + for i in $WANEC_LOAD_DRIVERS + do + $MODULE_STAT | grep -q $i && continue + + if ! load_driver $i + then + return 1 + fi + done + fi + + return 0 +} + + +lip_config () +{ + local opt=$1 + + if [ "$WAN_LIP_LOAD" != "YES" ]; then + return 0 + fi + + if [ $OSYSTEM != "FreeBSD" -a $OSYSTEM != "Linux" ]; then + return 0 + fi + + + file_exist $MOD9 + if [ $? -ne 0 ]; then + return 0 + fi + + if [ $DEPMOD != YES ]; then + return 0 + fi + + if [ $opt = UNLOAD ]; then + lsmods=`$MODULE_STAT` + + for i in $LIP_UNLOAD_DRIVERS + do + echo "$lsmods" | grep -q "$i" && { + if ! unload_driver $i + then + return 1 + fi + } + done + else + + for i in $LIP_LOAD_DRIVERS + do + $MODULE_STAT | grep -q $i && continue + + if ! load_driver $i + then + return 1 + fi + done + fi + + return 0 +} + + + +mod_error() +{ + echo -e "\n" + error "Wanpipe Module: $1 not found !!!" + if [ $OSYSTEM = "Linux" ]; then + echo -e " WANPIPE drivers must be compiled as modules" + echo -e " Check kernel configuration in /usr/src/linux/.config: " + echo -e " CONFIG_WAN_ROUTER=m" + echo -e " CONFIG_VENDOR_SANGOMA=m\n" + else + echo -e "WANPIPE drivers are modules files. " + echo -e "Try to re-compile WANPIPE drivers." + fi +} + +get_distrib() +{ + grep -i "red *hat" "/etc/issue" > /dev/null + if [ $? -eq 0 ] + then + return 1; #RedHat Found + else + return 0; + fi + +} + +check_config() +{ + for dev in $WAN_DEVICES; do + check_file "$WAN_CONF_DIR/$dev.conf" || { + echo -e "\n$SCRIPT: Error, $WAN_CONF_DIR/$dev.conf not found!\n"; + return 1; + } + done + return 0; +} + +check_file() +{ + local file=$1 + + [ ! -f "$file" ] && { + if [ ! -z $file ]; + then + echo -e "ERROR: Wanpipe configuration file not found: $file\n" + else + echo -e "ERROR: Wanpipe configuration file not found in $WAN_CONF_DIR\n" + fi + return 1; + } + return 0; +} + +print_active_devices() +{ + local ac_list; + local ac_wan; + local rc=0; + local silent=${1:-0} + local devices + + echo -e "Devices currently active:" + echo -en "\t" + + if [ $OSYSTEM = "Linux" ]; then + #If /proc directory doesn't exist nothing + #to print, thus exit + [ ! -d "$ROUTER_PROC" ] && return 0 + + devices=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort` + else + check_module + if [ $? -ne 0 ]; then + return 0 + fi + devices=`wanconfig status | cut -d' ' -f1 | grep wanpipe | sort` + fi + + if [ ! -z "$devices" ]; then + if [ $silent -ne 0 ]; then + echo $devices + fi + rc=1; + fi + + echo -e "\n" + + return $rc +} + +function check_exists () { + + local device=$1 + + if [ $OSYSTEM = "Linux" ]; then + [ ! -d "$ROUTER_PROC" ] && return 1 #Device not running + + if [ ! -f $ROUTER_PROC/$device ]; then + echo "Error: Device $device does not exist/not allocated." + echo " Check the messages log for the number of probed devices." + echo + return 1 + fi + fi + + # Device exists + return 0 + +} + +function check_dev_running () +{ + local device=$1 + local res + + if [ $OSYSTEM = "Linux" ]; then + [ ! -d "$ROUTER_PROC" ] && return 1 #Device not running + + res=`cat $ROUTER_PROC/status | grep "$device "` + else + check_module + if [ $? -ne 0 ]; then + return 1 + fi + res=`wanconfig status | grep "$device "` + fi + + [ ! -z "$res" ] && { + #Device running + return 0 + } + + #Device not running + return 1; +} + +check_and_print_still_running () +{ + local devices + + if [ $OSYSTEM = "Linux" ]; then + if [ ! -d $ROUTER_PROC ]; then + return 1 + fi + + devices=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort` + else + check_module + if [ $? -ne 0 ]; then + return 1 + fi + + devices=`wanconfig status | cut -d' ' -f1 | grep wanpipe | sort` + fi + + if [ ! -z "$devices" ]; then + echo "Devices Still Running:" + echo -ne "\t" + echo $devices + echo + return 0 + fi + + return 1 +} + +create_ft1_conf () { + + local dev=$1 + local res + + wandev=`grep "wanpipe.*=" $WAN_CONF_DIR/$dev.conf 2> /dev/null` + res=$? + if [ $res -eq 0 ]; then + wandev=${wandev%%=*} + if [ $AWK_SUPPORT = YES ]; then + eval "wandev=`echo $wandev | awk '{ gsub(" ", "") ; print }'`" + elif [ $BASH_SUPPORT -gt 1 ]; then + wandev=${wandev// /} + fi + else + echo -e "Error: Device name not found in $WAN_CONF_DIR/$dev.conf\n" + cleanup 1 + fi + + wancard=`grep "CARD_TYPE.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` + wancpu=`grep "S514CPU.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` + wanslot_auto=`grep "AUTO_PCISLOT.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` + wanslot=`grep "PCISLOT.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` + wanbus=`grep "PCIBUS.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` + wanio=`grep "IOPORT.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` + wanirq=`grep "IRQ.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` + + if [ -z "$wancard" ]; then + echo -e "Error: Missing fileds in $WAN_CONF_DIR/$dev.conf" + echo -e " configuraton file, in [$wandev] section.\n " + cleanup 1 + fi + + if [ -z "$wancpu" -o -z "$wanslot" ]; then + if [ -z "$wanio" -o -z "$wanirq" ]; then + echo -e "Error: Missing fileds in $WAN_CONF_DIR/$dev.conf" + echo -e " configuraton file, in [$wandev] section.\n " + cleanup 1 + fi + fi + + cat < $WAN_CONF_DIR/$FT1_CONF + +#FT1 Configuration File +# +# Note: This file was automatically generated by wanrouter +# script. +# DO NOT CHANGE IT +# +# CHDLC Protocol is used since, its firmware is the +# only one with FT1 configuration functions. + +[devices] + +$wandev = WAN_CHDLC, Cisco HDLC Firmware + +[$wandev] + +$wancard +$wancpu +$wanslot_auto +$wanslot +$wanbus + +$wanio +$wanirq + +Firmware = $WAN_HOME/firmware/cdual514.sfm # adapter firmware + +#--------------------- END OF FT1 CONFIGURATION ------------------------ + +EOM + +} + + +check_config_opt () +{ + local dev=$1 + local opt=$2 + + case $dev in + + ft1_wanpipe*) + + #Strip off 'ft1_' from 'ft1_wanpipe#' + dev=${dev##ft1_} + + #Check if wanpipe#.conf file exists + check_file "$WAN_CONF_DIR/$dev.conf" + if [ $? -gt 0 ]; then + cleanup 1 + fi + + #If we are starting the router up, create + #the ft1.conf file in $WAN_CONF_DIR directory + if [ $opt -eq 0 ]; then + create_ft1_conf $dev + fi + + #Return string ft1 + result "ft1" + + #Get the wanpipe device number, and return it + #as a return code. This indicates that we want + #to setup ft1 device + dev=${dev##wanpipe} + if [ $AWK_SUPPORT = YES ]; then + dev=`echo $dev | awk '{ gsub(" ", "") ; print }'` + elif [ $BASH_SUPPORT -gt 1 ]; then + dev=${dev// /} + fi + return $dev + ;; + + wanpipe*) + #Check if wanpipe#.conf file exists + check_file "$WAN_CONF_DIR/$dev.conf" + if [ $? -gt 0 ]; then + cleanup 1 + fi + + #return string wanpipe# + result $dev + + #return zero which indicates that we + #want to startup reglar wanpipe device + #not ft1 device + return 0 + ;; + + *) + #Illegal syntax obtained + echo "Error: Incorrect device name syntax !" + cleanup 1 + ;; + esac + +} + +check_ft1_config () +{ + local ft1=$1 + + if [ $ft1 = ft1 ]; then + return 0 + else + return 1 + fi +} + +result () { + echo $1 > $RC +} + +check_osystem () { + + if [ $OSYSTEM = "Linux" ]; then + + if [ -d $WAN_LOCK_DIR ]; then + return 0 + else + echo + echo "Warning: WAN_LOCK_DIR = $WAN_LOCK_DIR does not exist!" + echo "Please update the WAN_LOCK_DIR in /etc/wanpipe/wanrouter.rc" + echo + fi + + if [ -d /var/lock/subsys ]; then + WAN_LOCK_DIR=/var/lock/subsys + elif [ -d /var/lock ]; then + WAN_LOCK_DIR=/var/lock + else + WAN_LOCK_DIR=$WAN_CONF_DIR + fi + fi + +} + +wansock_config () +{ + local opt=$1 + + if [ $OSYSTEM != "Linux" ]; then + return 0 + fi + + file_exist $MOD5 + if [ $? -ne 0 ]; then + return 0 + fi + + if [ $DEPMOD != YES ]; then + return 0 + fi + + if [ $opt = UNLOAD ]; then + $MODULE_STAT | grep -q "$AF_WANPIPE" && { + unload_driver $AF_WANPIPE + } + else + load_driver $AF_WANPIPE + fi + return 0 +} + +annexg_config () +{ + local opt=$1 + + if [ $OSYSTEM != "Linux" ]; then + return 0 + fi + + if [ "$WAN_ANNEXG_LOAD" != "YES" ]; then + return 0 + fi + + file_exist $MOD6 + if [ $? -ne 0 ]; then + return 0 + fi + + file_exist $MOD7 + if [ $? -ne 0 ]; then + return 0 + fi + + file_exist $MOD8 + if [ $? -ne 0 ]; then + return 0 + fi + + if [ $DEPMOD != YES ]; then + return 0 + fi + + if [ $opt = UNLOAD ]; then + lsmods=`$MODULE_STAT` + + for i in $ANNEXG_UNLOAD_DRIVERS + do + echo "$lsmods" | grep -q "$i" && { + unload_driver $i + } + done + else + + for i in $ANNEXG_LOAD_DRIVERS + do + load_driver $i + done + fi + + return 0 +} + + +function print_wanpipe_config () { + + echo -e "Wanpipe Config:\n" + if [ $OSYSTEM = "Linux" ]; then + cat /proc/net/wanrouter/config | sort + else + wanconfig config + fi +} + +function print_wanrouter_status () { + + echo -e "\nWanrouter Status:\n" + if [ $OSYSTEM = "Linux" ]; then + cat /proc/net/wanrouter/status | sort + else + wanconfig status + fi +} + + +function print_config_summary () +{ + local pfiles; + local pfile; + local pdev; + + cd $WAN_HOME + + pfiles=`ls wanpipe*\.conf 2> /dev/null` + if [ $? -ne 0 ]; then + echo "No Wanpipe configuration files found in $WAN_HOME"; + return; + fi + + echo -e "Configuration File Summary in : $WAN_HOME\n" + + echo -e "Device\t\tProtocol\tType Cpu/Io Slot/Irq Bus\tState" + echo -e "------------------------------------------------------------------------" + + for pfile in $pfiles + do + + #Test for invalid file: wanpipe1.conf.tmp" + echo $pfile | grep ".*\..*\..*" > /dev/null 2> /dev/null + if [ $? -eq 0 ]; then + continue + fi + + + pdev=`grep "^wanpipe*=*" $pfile | cut -d'=' -f1 | cut -d' ' -f1 2> /dev/null` + if [ $? -ne 0 ]; then + continue + fi + if [ -z "$pdev" ]; then + continue + fi + + echo -e -n "$pdev\t" + + pprot=`grep "^wanpiped*=*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` + if [ $? -ne 0 ]; then + continue + fi + + if [ -z $pprot ]; then + continue + fi + + if [ $pprot = WAN_X25 ] || [ $pprot = WAN_PPP ] || [ $pprot = WAN_FR ] || [ $pprot = WAN_MFR ] || [ $pprot = WAN_BSC ] || [ $pprot = WAN_AFT ] || [ $pprot = WAN_SS7 ] || [ $pprot = WAN_POS ] || [ $pprot = WAN_ATM ]; then + echo -e -n "$pprot\t\t" + else + echo -e -n "$pprot\t" + fi + + phw=`grep "^S514CPU*" $pfile` + if [ $? -eq 0 ]; then + echo -e -n "PCI\t" + + pcpu=`grep -i "^S514CPU*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` + echo -e -n "$pcpu\t" + + pslot=`grep -i "^PCISLOT*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` + echo -e -n "$pslot\t" + pbus=`grep -i "^PCIBUS*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` + if [ -z $pbus ]; then + echo -e -n "0\t" + else + echo -e -n "$pbus\t" + fi + + else + if [ $pprot = WAN_ADSL ]; then + + echo -e -n "PCI\t" + + echo -e -n "N/A\t" + + pslot=`grep -i "^PCISLOT*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` + echo -e -n "$pslot\t" + pbus=`grep -i "^PCIBUS*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` + if [ -z $pbus ]; then + echo -e -n "0\t" + else + echo -e -n "$pbus\t" + fi + + else + + echo -n -e "ISA\t" + pport=`grep -i "^IOPORT*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` + echo -e -n "$pport\t" + pport=`grep -i "^IRQ*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` + echo -e -n "$pport\t" + + echo -e -n "n/a\t" + + fi + fi + + if [ $OSYSTEM = "Linux" ]; then + if [ -e /proc/net/wanrouter ]; then + pstate=`cat /proc/net/wanrouter/status | grep $pdev | cut -d'|' -f4 | awk '{ gsub(" ", "") ; print }'` + else + pstate="" + fi + else + + check_module + if [ $? -eq 0 ]; then + pstate=`wanconfig status | grep $pdev | cut -d'|' -f4 | awk '{ gsub(" ", "") ; print }'` + else + pstate="" + fi + fi + if [ -z $pstate ]; then + echo -e -n "Inactive\t" + else + echo -e -n "$pstate\t" + fi + + echo + + done +} + +function wanrouter_if_debug() +{ + echo + echo "Debug Info for $1" + echo + + echo "WANPIPE Release: $ROUTER_VERSION" + echo + echo + + eval "$IFCONFIG_LIST | grep -w $1 >> /dev/null 2>>/dev/null" + if [ $? -ne 0 ]; then + check_dev_running $1 + if [ $? -eq 0 ]; then + wanconfig -D $1 + return; + fi + + echo + echo "Error: Interface $1 does not exist!" + echo + cleanup 1 + return; + fi + + if [ ! -f /usr/sbin/wanpipemon ]; then + echo + echo "Error: /usr/sbin/wanpipemon not found" + echo "Solution: Re-install latest wanpipe release" + echo + return; + fi + + eval "/usr/sbin/wanpipemon -i $1 -c xm 2>> /dev/null" + if [ $? -ne 0 ]; then + echo + echo "Error: /usr/sbin/wanpipemon failed!" + echo " Make sure $1 is a valid wanpipe interface" + echo " Otherwise call Sangoma Tech Support" + echo + return + fi + + sleep 3 + + eval "/usr/sbin/wanpipemon -i $1 -c sc" + if [ $? -ne 0 ]; then + echo + echo "Error: /usr/sbin/wanpipemon failed!" + echo " Make sure $1 is a valid wanpipe interface" + echo " Otherwise call Sangoma Tech Support" + echo + return + fi + sleep 2 + eval "/usr/sbin/wanpipemon -i $1 -c sc" + if [ $? -ne 0 ]; then + echo + echo "Error: /usr/sbin/wanpipemon failed!" + echo " Make sure $1 is a valid wanpipe interface" + echo " Otherwise call Sangoma Tech Support" + echo + return + fi + + sleep 5 + + echo "Start WANPIPE /var/log/messages" + echo + if [ $OSYSTEM = "Linux" ]; then + eval "tail -n 200 /var/log/messages | grep -i \"[wanpipe|sdladrv]\" " + else + eval "tail -n 200 /var/log/messages | grep -i \"wanpipe\|sdladrv\" " + fi + echo + echo "End of WANPIPE /var/log/messages" + echo + + sleep 5 + + + echo + echo "---------- Starting Trace [ PRESS ENTER TO STOP ] ---------" + echo + sleep 3 + + eval "/usr/sbin/wanpipemon -i $1 -c tr" + if [ $? -ne 0 ]; then + echo + echo "Error: /usr/sbin/wanpipemon failed!" + echo " Make sure $1 is a valid wanpipe interface" + echo " Otherwise call Sangoma Tech Support" + echo + fi +} + +function wanrouter_debug () +{ + local err=0 + echo + + if [ ! -d ${WAN_HOME} ]; then + echo "Error: ${WAN_HOME} not found" + echo "Reason: Wanpipe not installed properly" + echo "Solution: Re-install wanpipe" + return + fi + + check_module + if [ $? -ne 0 ]; then + load_module + if [ $? -ne 0 ]; then + if [ $OSYSTEM = "Linux" ]; then + echo "Error: /proc/net/wanrouter not found" + fi + echo "Reason: Wanpipe kernel modules failed to load" + echo "Solution: Run 'wanrouter hwprobe' or 'wanrouter start'" + echo " Contact Sangoma Tech Support" + echo + return + fi + unload_module + fi + + if [ ! -f ${WAN_HOME}/wanpipe1.conf ]; then + echo "Warning: wanpipe1.conf configuration file not found" + echo "Reason: did not run /usr/sbin/wancfg to create it" + echo "Solution: run /usr/sbin/wancfg :)" + echo + err=1 + fi + + eval "grep -i invalid $WAN_LOG" + if [ $? -eq 0 ]; then + echo + echo "Error: Configuration file syntax error in $WAN_LOG" + echo "Reason: Miss-configuration: run 'wanrouter conflog'" + echo "Solution: Re-run /usr/sbin/wancfg and configure all variables " + echo + err=1 + fi + + eval "tail -n 20 /var/log/messages | grep -i \"wanpipe.*error[,:]\" " + if [ $? -eq 0 ]; then + echo "------------------------------------------" + echo "Error: Error occured during wanrouter startup/shutdown" + echo "Reason: Check /var/log/messages file: run 'wanrouter messages'" + echo "Solution: Review /var/log/messages and contact Sangoma Tech Support" + echo + err=1 + else + + eval "tail -n 20 /var/log/messages | grep -i \"sdladrv.*invalid[,:]\"" + if [ $? -eq 0 ]; then + echo "------------------------------------------" + echo "Error: Config error occured during wanrouter startup/shutdown" + echo "Reason: Check /var/log/messages file: run 'wanrouter messages'" + echo "Solution: Review /var/log/messages and contact Sangoma Tech Support" + echo + err=1 + else + + eval "tail -n 20 /var/log/messages | grep -i \"wanpipe.*warning\" " + if [ $? -eq 0 ]; then + echo "------------------------------------------" + echo "Warning: Warning occured during wanrouter startup/shutdown" + echo "Reason: Check /var/log/messages file" + echo "Solution: Review /var/log/messages and contact Sangoma Tech Support" + echo + err=1 + fi + fi + fi + + if [ $err -eq 0 ]; then + echo "Wanpipe environment/utilites/modules/operation OK" + fi + echo +} + +function check_command_exist () +{ + local cmd=$1 + local cmd_rc + + if [ $OSYSTEM = "Linux" ]; then + eval "type $1 > /dev/null 2> /dev/null" + else + eval "which $1 > /dev/null 2> /dev/null" + fi + cmd_rc=$? + + return $cmd_rc +} + +function init_meta_conf () +{ + ROUTER_BOOT= + WANPIPE_CONF_DIR= + WANPIPE_INTR_DIR= + ROUTER_LOG= + ROUTER_LOCK= + ROUTER_IP_FORWARD= + NEW_IF_TYPE= + WANCFG_LIB= + WAN_DEVICES= + + ROUTER_BOOT= + WAN_CONF_DIR= + WAN_INTR_DIR= + WAN_LOG= + WAN_LOCK= + WAN_LOCK_DIR= + WAN_IP_FORWARD= + NEW_IF_TYPE= + WAN_LIB_DIR= + WAN_ADSL_LIST= + WAN_DEVICES= +} + +function read_meta_conf () +{ + + if [ $OSYSTEM = "Linux" ]; then + WAN_HOME=/etc/wanpipe + elif [ $OSYSTEM = "FreeBSD" -o $OSYSTEM = "OpenBSD" ]; then + WAN_HOME=/usr/local/etc/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + fi + WAN_CONF_DIR=$WAN_HOME + META_CONF=$WAN_HOME/wanrouter.rc + WAN_INTR_DIR=$WAN_HOME/interfaces + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +function meta_conf_compatiblity () +{ + WAN_CONF_DIR=$WANPIPE_CONF_DIR + WAN_INTR_DIR=$WANPIPE_INTR_DIR + WAN_LOG=$ROUTER_LOG + WAN_LOCK=$ROUTER_LOCK + WAN_LOCK_DIR=${ROUTER_LOCK%/*} + WAN_IP_FORWARD=$ROUTER_IP_FORWARD + WAN_LIB_DIR=$WANCFG_LIB + WAN_ADSL_LIST=$WANPIPE_CONF_DIR/wan_adsl.list + +} + +function wanrouter_script() +{ + local cmd=$1 + local dev=$2 + local ifname=$3 + + #echo "Starting Script: $WAN_SCRIPTS_DIR/$dev-$ifname-$cmd" + + if [ "$ifname" != "" ]; then + #Interface name exists + if [ -f "$WAN_SCRIPTS_DIR/$dev-$ifname-$cmd" ]; then + eval "sh $WAN_SCRIPTS_DIR/$dev-$ifname-$cmd $dev $ifname" + fi + + elif [ "$dev" != "" ]; then + #Device name exists + if [ -f "$WAN_SCRIPTS_DIR/$dev-$cmd" ]; then + eval "sh $WAN_SCRIPTS_DIR/$dev-$cmd $dev" + fi + else + #Global Cmd + if [ -f "$WAN_SCRIPTS_DIR/$cmd" ]; then + eval "sh $WAN_SCRIPTS_DIR/$cmd" + fi + fi +} + +function generate_adsl_list() +{ + local vci=0; + local vpi=0; + + echo "35 0" > $WAN_ADSL_LIST + echo "35 8" >> $WAN_ADSL_LIST + + vci=30 + vpi=0 + while [ 1 ]; do + while [ 1 ]; do + + echo "$vci $vpi" >> $WAN_ADSL_LIST + + vpi=$((vpi+1)) + if [ $vpi = 10 ]; then + vpi=0 + break; + fi + done + + vci=$((vci+1)) + + if [ $vci -eq 40 ]; then + vci=30 + break; + fi + done +} + +# FIXME: Add code for BSD +function wan_force_unload_modules() +{ + if [ $OSYSTEM = "Linux" ]; then + if [ -e "$ROUTER_PROC/status" ]; then + wp_list=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort -r` + if [ -z $list ]; then + mod_list=`cat /proc/modules | grep wan | cut -d ' ' -f1 | xargs` + for tmp_mod in $mod_list + do + eval "rmmod $tmp_mod >> /dev/null 2>> /dev/null" + done + fi + fi + fi +} + +# FIXME: Add code for BSD +function stop_running_wanpipes () +{ + + if [ $OSYSTEM = "Linux" ]; then + if [ -e "$ROUTER_PROC/status" ]; then + wp_list=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort -r` + + for list in $wp_list + do + list=${list// /}; + if [ ! -z $list ]; then + eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" + wanrouter stop $list + fi + done + + wan_force_unload_modules + fi + fi +} + +function config_wanrouter_rc () +{ + local sequence + local num + local val + + cat << EOM + +WANPIPE STARTUP CONFIG + +Current Wanpipe devices configured +to start on bootup: + +$WAN_DEVICES + + Please specify new startup string: + eg: wanpipe1 wanpipe2 ... + + Note: Single space must exist between + device names. + +EOM + +echo -n "Enter Wanpipe Startup Sequence: " + +read sequence + +if [ -z "$sequence" ]; then + echo + echo "Error: startup sequence must contain at least one device name" + echo " eg: wanpipe1" + echo + return +fi + +eval "echo $sequence | grep \"wanpipe\d*\" > /dev/null 2> /dev/null" +if [ $? -ne 0 ]; then + echo + echo "Error: startup sequence must contain at least one device name" + echo " eg: wanpipe1" + echo + return +fi + +echo +echo "New Sequence is: $sequence" +echo + +getyn "Is the above sequence correct ?" + +if [ $? -eq 0 ]; then + echo + echo "Setting wanpipe startup sequence to: $sequence" + echo + cat $META_CONF | grep "WAN_DEVICES=" -v > $WAN_HOME/tmp.$$ + echo "WAN_DEVICES=\"$sequence\"" >> $WAN_HOME/tmp.$$ + cat $WAN_HOME/tmp.$$ > $META_CONF +fi + +} + + +####### MAIN ################################################################# +# set -x + +RCDLINKS="0,K10 1,K10 2,S20 3,S20 4,S20 5,S20 6,K10" + + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/loca/bin:/usr/local/sbin +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib + +OSYSTEM=`uname -s` +RELEASE=`uname -r` +PROD=wanpipe +SCRIPT=wanrouter +REDHAT=/usr/src/redhat +ROUTER_PROC=/proc/net/wanrouter +AF_WANPIPE=af_wanpipe +ANNEXG_LOAD_DRIVERS="wanpipe_lapb wanpipe_x25 wanpipe_dsp" +ANNEXG_UNLOAD_DRIVERS="wanpipe_dsp wanpipe_x25 wanpipe_lapb" +LIP_LOAD_DRIVERS="wanpipe_lip" +LIP_UNLOAD_DRIVERS="wanpipe_lip" +WANEC_LOAD_DRIVERS="wanec" +WANEC_UNLOAD_DRIVERS="wanec" +WAN_PROG_LOCK=/var/lock/wanrouter_lock +DEPMOD=YES +LINEPROBE_PATH=/usr/sbin/lineprobe +WANPIPE_IS_RUNNING=/var/run/wanpipe_is_running + +RUGGEDCOM=No + +if [ $OSYSTEM = "Linux" ]; then + ROUTER_VERSION=3.2.1 + IFCONFIG_LIST=ifconfig + MODULE_STAT=lsmod + WAN_DRIVERS="wanpipe" + MODULE_LOAD=modprobe + MODULE_UNLOAD="modprobe -r" + MODULE_EXT=".*" + DEPMOD=YES + + check_command_exist modprobe + if [ $? -ne 0 ]; then + check_command_exist insmod + if [ $? -eq 0 ]; then + DEPMOD=NO + MODULE_LOAD=insmod + MODULE_UNLOAD=rmmod + fi + fi + + MOD1=/lib/modules/sdladrv + MOD2=/lib/modules/wanrouter + MOD3=/lib/modules/wanpipe_syncppp + MOD4=/lib/modules/wanpipe + MOD5=/lib/modules/af_wanpipe + + if [ -d /lib/modules/$(uname -r) ]; then + uname -r | grep "^2.4.*" > /dev/null + if [ $? -eq 0 ]; then + if [ -d /lib/modules/$(uname -r)/kernel ]; then + MOD1=/lib/modules/$(uname -r)/kernel/drivers/net/wan/sdladrv + MOD2=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanrouter + MOD3=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_syncppp + MOD4=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe + MOD5=/lib/modules/$(uname -r)/kernel/net/wanrouter/af_wanpipe + + MOD6=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_lapb + MOD7=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_x25 + MOD8=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_dsp + MOD9=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanpipe_lip + MOD10=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanec + fi + else + + uname -r | grep "^2.6.*" > /dev/null + if [ $? -eq 0 ]; then + if [ -d /lib/modules/$(uname -r)/kernel ]; then + MOD1=/lib/modules/$(uname -r)/kernel/drivers/net/wan/sdladrv + MOD2=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanrouter + MOD3=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_syncppp + MOD4=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe + MOD5=/lib/modules/$(uname -r)/kernel/net/wanrouter/af_wanpipe + + MOD6=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_lapb + MOD7=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_x25 + MOD8=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_dsp + MOD9=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanpipe_lip + MOD10=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanec + fi + else + if [ -d /lib/modules/$(uname -r)/net ]; then + MOD1=/lib/modules/$(uname -r)/net/sdladrv + MOD2=/lib/modules/$(uname -r)/misc/wanrouter + MOD3=/lib/modules/$(uname -r)/net/wanpipe_syncppp + MOD4=/lib/modules/$(uname -r)/net/wanpipe + MOD5=/lib/modules/$(uname -r)/misc/af_wanpipe + + MOD6=/lib/modules/$(uname -r)/net/wanpipe_lapb + MOD7=/lib/modules/$(uname -r)/net/wanpipe_x25 + MOD8=/lib/modules/$(uname -r)/net/wanpipe_dsp + MOD9=/lib/modules/$(uname -r)/misc/wanpipe_lip + MOD10=/lib/modules/$(uname -r)/misc/wanec + fi + fi + fi + fi + + MODULES="$MOD1 $MOD2 $MOD3 $MOD4 $MOD5" + OPT_MODULES="$MOD3 $MOD5" + UMODULES="af_wanpipe wanpipe wanpipe_syncppp wanrouter sdladrv" + +elif [ $OSYSTEM = "FreeBSD" ]; then + + SYSCTL=/sbin/sysctl + AWK=/usr/bin/awk + PKGINFO=/usr/sbin/pkg_info + major_ver=${RELEASE%%.*} + ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` + IFCONFIG_LIST=ifconfig + CDEV_WANROUTER=/dev/$SCRIPT + CDEV_MAJOR=139 + CDEV_MINOR=0 + MODULE_STAT=kldstat + MODULE_LOAD=kldload + MODULE_UNLOAD=kldunload + MODULE_EXT=".*" + + if [ "$major_ver" = "5" -o "$major_ver" = "6" ]; then + MODULE_DIR=/boot/modules + else + MODULE_DIR=/modules + fi + MOD9="$MODULE_DIR/wanpipe_lip" + MOD10="$MODULE_DIR/wanec" + MODULES="$MODULE_DIR/wanrouter $MODULE_DIR/sdladrv $MODULE_DIR/wanpipe" + WAN_DRIVERS="wanpipe" + +elif [ $OSYSTEM = "OpenBSD" ]; then + + SYSCTL=/sbin/sysctl + AWK=/usr/bin/awk + PKGINFO=/usr/sbin/pkg_info + SECURELEVEL=`$SYSCTL -n kern.securelevel` + ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` + IFCONFIG_LIST="ifconfig -a" + CDEV_WANROUTER=/dev/$SCRIPT + CDEV_MAJOR=139 + CDEV_MINOR=0 + POSTINSTALL=create_cdev + MODULE_STAT=modstat + MODULE_LOAD=modload + MODULE_UNLOAD=modunload + MODULE_DIR=/usr/lkm + MODULE_EXT=".o" + MODULES="$MODULE_DIR/wanpipe" + WAN_DRIVERS="wanpipe" +elif [ $OSYSTEM = "NetBSD" ]; then + + SYSCTL=/sbin/sysctl + AWK=/usr/bin/awk + PKGINFO=/usr/sbin/pkg_info + SECURELEVEL=`$SYSCTL -n kern.securelevel` + ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` + IFCONFIG_LIST="ifconfig -a" + CDEV_WANROUTER=/dev/$SCRIPT + CDEV_MAJOR=139 + CDEV_MINOR=0 + POSTINSTALL=create_cdev + MODULE_STAT=modstat + MODULE_LOAD=modload + MODULE_UNLOAD=modunload + MODULE_DIR=/usr/lkm + MODULE_EXT=".o" + MODULES="$MODULE_DIR/wanpipe" + WAN_DRIVERS="wanpipe" +fi + +check_bash +check_awk + + +# Return code +RC=$(pwd)/return_code +GET_RC="cat $RC" +FT1_CONF=ft1.conf + +# Ignore interrupt signals. +trap '' 2 + +init_meta_conf +read_meta_conf +if [ $? -ne 0 ]; then + echo "$SCRIPT: Error: $META_CONF not found!" + exit 1; +fi + +if [ "$WANPIPE_CONF_DIR" != "" -a "$WAN_CONF_DIR" = "" ] || [ "$WAN_ADSL_LIST" = "" ]; then + meta_conf_compatiblity +fi + +WAN_LIP_LOAD=YES +WANEC_LOAD=YES +WAN_ANNEXG_LOAD=${WAN_ANNEXG_LOAD:-NO} +WAN_DYN_WANCONFIG=${WAN_DYN_WANCONFIG:-NO} +NEW_IF_TYPE=${NEW_IF_TYPE:-NO} +WAN_INTR_DIR=$WAN_INTR_DIR +LINUX_DISTR=unknown + + +if [ -f $WAN_PROG_LOCK ]; then + echo -e "\nERROR: wanrouter script already running!\n"; + cleanup 0; +fi + +touch $WAN_PROG_LOCK + +check_osystem + +#Check osystem confirms the WAN_LOCK directory +WAN_LOCK=$WAN_LOCK_DIR/wanrouter + + +if [ ! -f $WAN_ADSL_LIST ]; then + generate_adsl_list +fi + +if [ $OSYSTEM = "Linux" ]; then + eval "grep \"Debian\" -i /etc/issue > /dev/null" + if [ $? -eq 0 ]; then + LINUX_DISTR=debian + fi + eval "grep \"Red *Hat\" -i /etc/issue > /dev/null" + if [ $? -eq 0 ]; then + LINUX_DISTR=redhat + fi + eval "grep \"Mandrake\" -i /etc/issue > /dev/null" + if [ $? -eq 0 ]; then + LINUX_DISTR=redhat + fi + + if [ "$WAN_DYN_WANCONFIG" = "YES" ]; then + if [ ! -e "/etc/wanpipe/wanconfig_socket" ]; then + echo "Starting wanconfig dameon" + eval "/usr/sbin/wanconfig -x >> $WAN_LOG 2>> $WAN_LOG &" + if [ $? -ne 0 ]; then + echo "Failed to start wanconfig daemon!" + cleanup 0; + fi + else + if [ ! -e "/var/run/wanconfig.pid" ]; then + echo "Starting wanconfig dameon" + \rm -f /etc/wanpipe/wanconfig_socket + eval "/usr/sbin/wanconfig -x >> $WAN_LOG 2>> $WAN_LOG &" + if [ $? -ne 0 ]; then + echo "Failed to start wanconfig daemon!" + cleanup 0; + fi + else + kill -USR1 $(cat /var/run/wanconfig.pid) >> /dev/null 2>> /dev/null + if [ $? -ne 0 ]; then + echo "Starting wanconfig dameon" + \rm -f /etc/wanpipe/wanconfig_socket + eval "/usr/sbin/wanconfig -x >> $WAN_LOG 2>> $WAN_LOG &" + if [ $? -ne 0 ]; then + echo "Failed to start wanconfig daemon!" + cleanup 0; + fi + fi + fi + fi + else + if [ -e "/etc/wanpipe/wanconfig_socket" ]; then + if [ -f /var/run/wanconfig.pid ]; then + eval "kill -TERM $(cat /var/run/wanconfig.pid)" + echo "Killing wanconfig daemon" + fi + fi + fi +fi + + +echo +# If modules doesn't loaded remove all lock file from WAN_LOCK_DIR. +check_module + +ft1_or_wanpipe=0 +# See how we were called. +case "$1" in + start) + + # WANROUTER START + if [ -z $2 ]; then + + check_config || cleanup 1 + + load_module + if [ $? -ne 0 ]; then + cleanup 2 + fi + + config_devices $WAN_DEVICES + + config_interfaces $WAN_DEVICES + + wanrouter_script start + + elif [ -z $3 ]; then + #ROUTER START WANPIPE + + [ -f $WAN_CONF_DIR/$FT1_CONF ] && rm -f $WAN_CONF_DIR/$FT1_CONF + dev=$2 + + #Parse the dev name, and if it starts with + #ft1 than it means we should load the ft1 + #driver. + check_config_opt $dev 0 + ft1_or_wanpipe=$? + dev=$($GET_RC) + rm -f $RC + + WAN_CONF=$WAN_CONF_DIR/$dev.conf + + check_file $WAN_CONF || cleanup 1 + + load_module + if [ $? -ne 0 ]; then + cleanup 2 + fi + + #If we are starting FT1 driver, we have to check + #wether the actual wanpipe# device is running or + #not, thus name dev has to be changed to 'wanpipe#' + if [ $ft1_or_wanpipe -gt 0 ]; then + dev="wanpipe$ft1_or_wanpipe" + fi + + config_devices $dev + if [ $? -ne 0 ]; then + cleanup 3 + fi + + #When loading ft1 device there are not interfaces + if [ $ft1_or_wanpipe -eq 0 ]; then + config_interfaces $dev + if [ $? -ne 0 ]; then + cleanup 4 + fi + fi + + else + #ROUTER START WANPIPE INTERFACE + + if [ $OSYSTEM != "Linux" ]; then + echo " This option doesn't supported yet!" + cleanup 0 + fi + dev=$2 + if_name=$3 + + #Parse the dev name, and if it starts with + #ft1 than it means we should load the ft1 + #driver. + check_config_opt $dev 0 + ft1_or_wanpipe=$? + dev=$($GET_RC) + rm -f $RC + + WAN_CONF=$WAN_CONF_DIR/$dev.conf + + check_file $WAN_CONF || cleanup 1 + + load_module + if [ $? -ne 0 ]; then + cleanup 2 + fi + + eval "$IFCONFIG_LIST | grep -w $if_name > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo -e "\nInterface $if_name is already up!\n" + cleanup 1 + fi + + echo "Configuring interface: $if_name" + + if [ "$WAN_DYN_WANCONFIG" = YES ]; then + eval "/usr/sbin/wanconfig_client cmd=start,card=$dev,dev=$if_name" + else + eval "/usr/sbin/wanconfig -v card $dev dev $if_name up >> $WAN_LOG" + fi + + + #Regardles of config try to bring up the interface + #Interface up command will fail on its own + #if [ $? -ne 0 ]; then + # cleanup 1 + #fi + + interface_up $if_name + if [ $? -ne 0 ]; then + echo -e "\nInterface $if_name start error: ip setup failure!\n" + cleanup 1 + else + echo "Interface $if_name up." + fi + + wanrouter_script start $dev $if_name + fi + ;; + stop) + + #WANROUTER STOP + if [ -z $2 ]; then + + check_module + if [ $? -ne 0 ]; then + unload_module + remove_cdev + echo -e "Router is already stopped !\n" + cleanup 1 + fi + + #Check that all wanpipe#.conf file defined in + # WAN_DEVICES exist + check_config || { + unload_module + remove_cdev + echo -e "No devices running, Unloading Modules" + cleanup 1 + } + + if [ "$WAN_DEVICES_REV_STOP_ORDER" = "YES" ]; then + tmp_dev_list= + for dev in $WAN_DEVICES; do + tmp_dev_list="$dev ""$tmp_dev_list" + done + WAN_DEVICES=$tmp_dev_list + fi + + unconfig_interfaces $WAN_DEVICES + + unconfig_devices $WAN_DEVICES + + wanrouter_script stop + + elif [ -z $3 ]; then + #WANROUTER STOP WANPIPE + + dev=$2 + + if [ "$dev" = "all" ]; then + stop_running_wanpipes + cleanup 0 + fi + + check_config_opt $dev 1 + ft1_or_wanpipe=$? + dev=$($GET_RC) + rm -f $RC + + #Check that modules are up and running + check_module + if [ $? -ne 0 ]; then + unload_module + echo -e "Router is already stopped !\n"; + cleanup 1; + fi + + #If we are stopping FT1 driver, we have to check + #whether the actual wanpipe# device is running or + #not, thus name dev has to be changed to 'wanpipe#' + if [ $ft1_or_wanpipe -gt 0 ]; then + dev="wanpipe$ft1_or_wanpipe" + fi + + if [ $ft1_or_wanpipe -eq 0 ]; then + unconfig_interfaces $dev + fi + + unconfig_devices $dev + + [ -f $WAN_CONF_DIR/$FT1_CONF ] && rm -f $WAN_CONF_DIR/$FT1_CONF + + else + if [ $OSYSTEM != "Linux" ]; then + echo " This option doesn't supported yet!" + cleanup 0 + fi + dev=$2 + if_name=$3 + + #Parse the dev name, and if it starts with + #ft1 than it means we should load the ft1 + #driver. + check_config_opt $dev 0 + ft1_or_wanpipe=$? + dev=$($GET_RC) + rm -f $RC + + WAN_CONF=$WAN_CONF_DIR/$dev.conf + + check_file $WAN_CONF || cleanup 1 + + eval "$IFCONFIG_LIST | grep -w $if_name > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "Interface $if_name down" + eval "ifconfig $if_name down" + fi + + echo "Unconfiguring interface: $if_name" + if [ "$WAN_DYN_WANCONFIG" = YES ]; then + eval "/usr/sbin/wanconfig_client cmd=stop,card=$dev,dev=$if_name" + else + eval "/usr/sbin/wanconfig -v card $dev dev $if_name down >> $WAN_LOG" + fi + if [ $? -ne 0 ]; then + cleanup 1 + fi + + check_and_print_still_running && cleanup 0 + + cd $WAN_HOME + echo -e "No devices running, Unloading Modules" + unload_module + + wanrouter_script stop $dev $if_name + fi + ;; + + start_dev) + + if [ -z $2 ]; then + # WANROUTER START_DEV + + check_config || cleanup 1 + + load_module + if [ $? -ne 0 ]; then + cleanup 2 + fi + + config_devices $WAN_DEVICES + + elif [ -z $3 ]; then + #ROUTER START_DEV WANPIPE + + dev=$2 + + load_module + if [ $? -ne 0 ]; then + cleanup 2 + fi + + config_devices $dev + if [ $? -ne 0 ]; then + cleanup 3 + fi + fi + ;; + + stop_dev) + + if [ -z $2 ]; then + #WANROUTER STOP_DEV + + check_module + if [ $? -ne 0 ]; then + unload_module + remove_cdev + echo -e "Router is already stopped !\n" + cleanup 1 + fi + + #Check that all wanpipe#.conf file defined in + # WAN_DEVICES exist + check_config || { + unload_module + remove_cdev + echo -e "No devices running, Unloading Modules" + cleanup 1 + } + + if [ "$WAN_DEVICES_REV_STOP_ORDER" = "YES" ]; then + tmp_dev_list= + for dev in $WAN_DEVICES; do + tmp_dev_list="$dev ""$tmp_dev_list" + done + WAN_DEVICES=$tmp_dev_list + fi + + unconfig_devices $WAN_DEVICES + + wanrouter_script stop + + elif [ -z $3 ]; then + #WANROUTER STOP_DEV WANPIPE + + dev=$2 + + if [ "$dev" = "all" ]; then + stop_running_wanpipes + cleanup 0 + fi + + #Check that modules are up and running + check_module + if [ $? -ne 0 ]; then + unload_module + echo -e "Router is already stopped !\n"; + cleanup 1; + fi + + unconfig_devices $dev + fi + ;; + + start_ip) + + if [ -z $2 ]; then + # WANROUTER START_IP + check_config || cleanup 1 + + config_interfaces $WAN_DEVICES + + wanrouter_script start + + elif [ -z $3 ]; then + #ROUTER START_IP WANPIPE + config_interfaces $2 + fi + ;; + + stop_ip) + + if [ -z $2 ]; then + #WANROUTER STOP_IP + unconfig_interfaces $WAN_DEVICES + + elif [ -z $3 ]; then + #WANROUTER STOP_IP WANPIPE + unconfig_interfaces $2 + fi + ;; + + script) + + #Debug Statement, used to test the script option + #echo "WAN_ACTION=$WAN_ACTION WAN_DEVICE=$WAN_DEVICE WAN_INTERFACE=$WAN_INTERFACE" >> /var/log/messages + + #wanrouter script + if [ ! -z $WAN_ACTION ]; then + if [ ! -z $WAN_INTERFACE ]; then + wanrouter_script $WAN_ACTION $WAN_DEVICE $WAN_INTERFACE + elif [ ! -z $WAN_DEVICE ]; then + wanrouter_script $WAN_ACTION $WAN_DEVICE + else + wanrouter_script $WAN_ACTION + fi + fi + ;; + + list) + + check_module + if [ $? -ne 0 ]; then + echo -e "Router is stopped !\n"; + cleanup 0; + fi + + print_active_devices 1; + cleanup 0; + ;; + + restart) + eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" + if [ "$2" = "" ]; then + $0 stop; + $0 start; + elif [ "$3" = "" ]; then + $0 stop $2; + $0 start $2; + else + $0 stop $2 $3; + $0 start $2 $3; + fi + cleanup 0; + ;; + + restart_dev) + eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" + if [ "$2" = "" ]; then + $0 stop_dev; + $0 start_dev; + elif [ "$3" = "" ]; then + $0 stop_dev $2; + $0 start_dev $2; + fi + cleanup 0; + ;; + + restart_ip) + eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" + if [ "$2" = "" ]; then + $0 stop_ip; + $0 start_ip; + elif [ "$3" = "" ]; then + $0 stop_ip $2; + $0 start_ip $2; + fi + cleanup 0; + ;; + + modules) + + if [ $OSYSTEM = "Linux" ]; then + cat /proc/modules | grep wan; + else + $MODULE_STAT | grep -i "wan\|sdla"; + #$MODULE_STAT | grep sdla; + fi + cleanup 0; + + ;; + status) + + check_module + if [ $? -ne 0 ]; then + echo -e "Router is stopped !\n"; + cleanup 0; + fi + + print_active_devices 1; + print_wanpipe_config + print_wanrouter_status + echo "" + + cleanup 0; + ;; + + + summary) + print_config_summary; + cleanup 0; + ;; + + hwprobe) + load_module silent + if [ $? -ne 0 ]; then + cleanup 1 + fi + if [ "$2" = "verbose" ]; then + if [ $OSYSTEM = "Linux" ]; then + cat /proc/net/wanrouter/hwprobe_verbose + else + wanconfig hwprobe verbose + fi + else + if [ $OSYSTEM = "Linux" ]; then + cat /proc/net/wanrouter/hwprobe + else + wanconfig hwprobe + fi + fi + cleanup 0; + ;; + + debug) + if [ -z $2 ]; then + wanrouter_debug; + else + wanrouter_if_debug $2; + fi + cleanup 0; + ;; + + wanrc) + + config_wanrouter_rc + cleanup 0; + ;; + + messages) + echo + echo "Start WANPIPE /var/log/messages" + echo + if [ $OSYSTEM = "Linux" ]; then + eval "tail -n 200 /var/log/messages | grep -i \"[wanpipe|sdladrv]\" " + else + eval "tail -n 200 /var/log/messages | grep -i \"wanpipe\|sdladrv\" " + fi + echo + echo "End of WANPIPE /var/log/messages" + echo + cleanup 0; + ;; + + conflog) + echo + echo "Start WANPIPE $WAN_LOG" + echo + eval "cat $WAN_LOG" + echo + echo "End of WANPIPE $WAN_LOG" + echo + cleanup 0; + ;; + + version) + echo "WANPIPE Release: $ROUTER_VERSION" + ;; + + lineprobe) + if [ $OSYSTEM != "Linux" ]; then + echo -e "The 'lineprobe' option supported on Linux OS only.\n" + cleanup 1; + fi + + echo -e "Starting the lineprobe ...\n" + + #The lineprobe calls wanrouter internally. + #This instance of wanrouter will prevent the other from starting. + #Remove the lock. + eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" + + #Remove name of the program from command line. + shift 1 + #Pass rest of the arguments to lineprobe. + if [ -e $LINEPROBE_PATH ]; then + eval "lineprobe" "$@" + else + echo -e "File $LINEPROBE_PATH does not exist!" + echo -e "Please check 'lineprobe' was successfully compiled.\n" + fi + + ;; + + *) echo -e "\nWANPIPE: WAN Router startup script\n" + echo -e "Usage: $SCRIPT: {options} \n" + + echo -e " wanrouter start : Starts all devices specified in" + echo -e " $WAN_CONF_DIR/wanrouter.rc WAN_DEVICES\n" + echo -e " wanrouter stop : Stops all devices specified in" + echo -e " $WAN_CONF_DIR/wanrouter.rc WAN_DEVICES\n" + echo -e " wanrouter start wanpipe# : Start a single device\n" + echo -e " wanrouter stop wanpipe# : Stops a single device" + echo -e " (# can range from 1 to 16)\n" + if [ $OSYSTEM = "Linux" ]; then + echo -e " wanrouter start wanpipe# if_name : Start a single interface on device\n" + echo -e " wanrouter stop wanpipe# if_name : Stops a single interface on device" + echo -e " (# can range from 1 to 16)\n" + + fi + echo -e " wanrouter restart : Restart all devices specified in" + echo -e " $WAN_CONF_DIR/wanrouter.rc WAN_DEVICES\n" + echo -e " wanrouter restart wanpipe# : Restart a single device" + echo -e " (# can range from 1 to 16)\n" + echo + if [ $OSYSTEM = "Linux" ]; then + echo -e " wanrouter restart wanpipe# if_name : Restart a single interface on device" + echo -e " (# can range from 1 to 16)\n" + echo + fi + echo -e " wanrouter list : List all active devices\n" + echo -e " wanrouter modules : Show wanpipe kernel modules\n" + echo -e " wanrouter status : Display status for all active devices\n" + echo -e " wanrouter summary : Summary of config files in $WAN_HOME\n" + echo -e " wanrouter hwprobe : Display wanpipe hardware probe info.\n" + echo -e " wanrouter debug : Check current wanpipe environment." + echo -e " After a startup error run this command to" + echo -e " get a possible solution" + echo -e " i.e. wanrouter start; wanrouter debug;\n" + if [ $OSYSTEM = "Linux" ]; then + echo -e " wanrouter debug if_name : Display common debugging statistics" + echo -e " In case of line problems save to file," + echo -e " wait 2-5mi and send to Sangoma Tech Support" + echo -e " i.e. wanrouter debug wp1fr16 > debug_file;\n" + fi + echo -e " wanrouter messages : Display wanpipe kernel event messages" + echo -e " i.e. /var/log/messages\n" + echo -e " wanrouter conflog : Display wanpipe configuration parsing messages" + echo -e " i.e. $WAN_LOG\n" + echo -e " wanrouter wanrc : Configure the wanpipe boot startup order" + echo -e " in $META_CONF\n" + echo -e " wanrouter version : wanpipe version information.\n" + + if [ $OSYSTEM = "Linux" ]; then + echo -e " wanrouter lineprobe [-c wanpipe#] [options] " + echo -e " : Monitor/Debug a line connected to an" + echo -e " automatically detected or preconfigured card." + echo -e " i.e.: wanrouter lineprobe; or" + echo -e " : wanrouter lineprobe -c wanpipe1;" + echo -e " Type 'wanrouter lineprobe -help' to get the" + echo -e " list of 'lineprobe' options." + fi + cleanup 0 + ;; +esac +echo +cleanup 0 +exit 0 diff --git a/ssmg/sangoma_mgd.trunk/.svn/all-wcprops b/ssmg/sangoma_mgd.trunk/.svn/all-wcprops index 3436afa..bd91566 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/all-wcprops +++ b/ssmg/sangoma_mgd.trunk/.svn/all-wcprops @@ -1,25 +1,13 @@ K 25 svn:wc:ra_dav:version-url V 34 -/svn/sangoma_mgd/!svn/ver/24/trunk +/svn/sangoma_mgd/!svn/ver/58/trunk END sigboost.h K 25 svn:wc:ra_dav:version-url V 45 -/svn/sangoma_mgd/!svn/ver/22/trunk/sigboost.h -END -sound.raw -K 25 -svn:wc:ra_dav:version-url -V 43 -/svn/sangoma_mgd/!svn/ver/1/trunk/sound.raw -END -sangoma_mgd.conf.sample -K 25 -svn:wc:ra_dav:version-url -V 58 -/svn/sangoma_mgd/!svn/ver/22/trunk/sangoma_mgd.conf.sample +/svn/sangoma_mgd/!svn/ver/36/trunk/sigboost.h END switch_buffer.h K 25 @@ -27,6 +15,18 @@ svn:wc:ra_dav:version-url V 49 /svn/sangoma_mgd/!svn/ver/1/trunk/switch_buffer.h END +sangoma_mgd.conf.sample +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/sangoma_mgd/!svn/ver/25/trunk/sangoma_mgd.conf.sample +END +sound.raw +K 25 +svn:wc:ra_dav:version-url +V 43 +/svn/sangoma_mgd/!svn/ver/1/trunk/sound.raw +END callgettest.sh K 25 svn:wc:ra_dav:version-url @@ -39,35 +39,29 @@ svn:wc:ra_dav:version-url V 40 /svn/sangoma_mgd/!svn/ver/1/trunk/ss7box END -Changelog -K 25 -svn:wc:ra_dav:version-url -V 43 -/svn/sangoma_mgd/!svn/ver/1/trunk/Changelog -END -call_signal.c -K 25 -svn:wc:ra_dav:version-url -V 47 -/svn/sangoma_mgd/!svn/ver/1/trunk/call_signal.c -END re-sync.sh K 25 svn:wc:ra_dav:version-url V 45 /svn/sangoma_mgd/!svn/ver/20/trunk/re-sync.sh END -woomera.conf +call_signal.c K 25 svn:wc:ra_dav:version-url -V 46 -/svn/sangoma_mgd/!svn/ver/1/trunk/woomera.conf +V 48 +/svn/sangoma_mgd/!svn/ver/42/trunk/call_signal.c END sangoma_mgd.c K 25 svn:wc:ra_dav:version-url V 48 -/svn/sangoma_mgd/!svn/ver/24/trunk/sangoma_mgd.c +/svn/sangoma_mgd/!svn/ver/57/trunk/sangoma_mgd.c +END +woomera.conf +K 25 +svn:wc:ra_dav:version-url +V 46 +/svn/sangoma_mgd/!svn/ver/1/trunk/woomera.conf END call_signal.h K 25 @@ -79,7 +73,13 @@ sangoma_mgd.h K 25 svn:wc:ra_dav:version-url V 48 -/svn/sangoma_mgd/!svn/ver/22/trunk/sangoma_mgd.h +/svn/sangoma_mgd/!svn/ver/58/trunk/sangoma_mgd.h +END +Changelog.sangoma_mgd +K 25 +svn:wc:ra_dav:version-url +V 56 +/svn/sangoma_mgd/!svn/ver/55/trunk/Changelog.sangoma_mgd END q931_cause.h K 25 @@ -97,13 +97,13 @@ install K 25 svn:wc:ra_dav:version-url V 42 -/svn/sangoma_mgd/!svn/ver/20/trunk/install +/svn/sangoma_mgd/!svn/ver/51/trunk/install END smg_ctrl K 25 svn:wc:ra_dav:version-url -V 42 -/svn/sangoma_mgd/!svn/ver/1/trunk/smg_ctrl +V 43 +/svn/sangoma_mgd/!svn/ver/56/trunk/smg_ctrl END switch_buffer.c K 25 @@ -115,5 +115,5 @@ Makefile K 25 svn:wc:ra_dav:version-url V 43 -/svn/sangoma_mgd/!svn/ver/21/trunk/Makefile +/svn/sangoma_mgd/!svn/ver/48/trunk/Makefile END diff --git a/ssmg/sangoma_mgd.trunk/.svn/entries b/ssmg/sangoma_mgd.trunk/.svn/entries index b32f46a..97a618c 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/.svn/entries @@ -1,14 +1,14 @@ 8 dir -24 +58 https://www.sangomapbx.com:/svn/sangoma_mgd/trunk https://www.sangomapbx.com:/svn/sangoma_mgd -2007-10-03T19:40:43.713609Z -24 +2008-01-18T23:17:38.335382Z +58 ncorbic @@ -32,10 +32,10 @@ file -2007-10-03T19:44:50.000000Z -efa9458b6df577c673d9275d4eab1a6d -2007-10-02T16:32:47.773679Z -22 +2007-11-26T01:25:46.000000Z +d2023784f5d89a5623927a366705e22a +2007-11-24T22:45:32.820698Z +36 ncorbic app @@ -60,10 +60,10 @@ file -2007-10-03T19:44:50.000000Z -bf66f72830158267cef4cfa0fc72cfb6 -2007-10-02T16:32:47.773679Z -22 +2007-10-18T17:51:26.000000Z +6f5866feb746caa979c0c4df03517326 +2007-10-16T22:33:32.246854Z +25 ncorbic switch_buffer.h @@ -100,7 +100,7 @@ file -2007-09-21T20:55:42.000000Z +2007-12-21T21:08:30.000000Z f20dab977386b2508903e24a307ca2d6 2007-09-21T20:53:51.260136Z 1 @@ -113,29 +113,17 @@ svn:special scripts dir -Changelog -file - - - - -2007-09-21T20:55:42.000000Z -e882d77b92b36e5878240af27f94d36f -2007-09-21T20:53:51.260136Z -1 -root - call_signal.c file -2007-09-21T20:55:42.000000Z -b77f050a0ef676f8f1a558d07b48f11a -2007-09-21T20:53:51.260136Z -1 -root +2007-11-28T21:14:37.000000Z +bcf6ba51a26281d7a0963c364f8610f1 +2007-11-28T21:12:42.416435Z +42 +ncorbic re-sync.sh file @@ -156,10 +144,10 @@ file -2007-10-03T19:44:50.000000Z -b7dd5f313c998033b1d50cc444053f32 -2007-10-03T19:40:43.713609Z -24 +2008-01-18T23:23:07.000000Z +0dd2e3aad304bc37895c78f158afb0a3 +2008-01-18T23:01:23.237257Z +57 ncorbic woomera.conf @@ -192,10 +180,22 @@ file -2007-10-03T19:44:50.000000Z -ee879b15f742bdeb502b3265e2dd7b2c -2007-10-02T16:32:47.773679Z -22 +2008-01-18T23:23:07.000000Z +980fdef03b9982e8411a1e3a0d45a57d +2008-01-18T23:17:38.335382Z +58 +ncorbic + +Changelog.sangoma_mgd +file + + + + +2008-01-18T21:45:09.000000Z +c7ac5bb8faff69307d9e2739737a50b1 +2008-01-18T20:46:37.372416Z +55 ncorbic q931_cause.h @@ -231,10 +231,10 @@ file -2007-09-25T02:05:45.000000Z -01bc4e56da44f0619c948fa36799c0a3 -2007-09-25T02:04:57.936973Z -20 +2007-12-20T17:31:41.000000Z +0e00003cd276e523b9b6e6df6a2f823f +2007-12-20T00:59:56.095828Z +51 ncorbic has-props @@ -244,11 +244,11 @@ file -2007-09-25T00:59:32.000000Z -387bbb12c7561cc036617e5ce9b4cab5 -2007-09-21T20:53:51.260136Z -1 -root +2008-01-18T21:45:09.000000Z +305c8fe9341c230ec32af102688736fd +2008-01-18T20:47:52.049290Z +56 +ncorbic has-props switch_buffer.c @@ -269,9 +269,9 @@ file -2007-09-25T02:17:36.000000Z -3e70402d7a99c4e8a60224063a9037a0 -2007-09-25T02:15:46.259214Z -21 +2007-12-05T19:56:32.000000Z +7f772a76025b629be3915375ccbf5034 +2007-12-05T18:26:50.890720Z +48 ncorbic diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/Changelog.sangoma_mgd.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/Changelog.sangoma_mgd.svn-base new file mode 100644 index 0000000..998bae2 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/text-base/Changelog.sangoma_mgd.svn-base @@ -0,0 +1,112 @@ +sangoma_mgd.c +====================================== +Jan 18 2007 + * v1.26 Nenad Corbic + * Fixed hangup after invalid Answer or Ack Session + * Can cause double use of setup id - now fixed + * +Dec 31 2007 + * v1.25 Nenad Corbic + * Removed UDP Resync it can cause skb_over errors. + * Moved RDNIS message to higher debug level + +Nov 30 2007 + * v1.24 Nenad Corbic + * Bug fix on return code on ALL ckt busy + * + +Nov 28 2007 + + * v1.23 Nenad Corbic + * Bug fix on socket open. Check for retun code >= 0 + * + + * v1.22 Nenad Corbic + * Nov 27 2007 + * Updated DTMF Tx function + * Fixed - dtmf tx without voice + * Fxied - dtmf clipping. + + +Nov 22 2007 + + * v1.21 Nenad Corbic + * Major unit testing of each state + * Numerous bug fixes for non autoacm mode. + * Changed "Channel-Name" to tg/cic + * Added compile option WANPIPE_CHAN_NAME to change Asterisk channel + * name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE}) + * instead of WOOMERA (for example) + * + * v1.20 Nenad Corbic + * Added option for Auto ACM response mode. + * + * v1.19 Nenad Corbic + * Configurable DTMF + * Bug fix in release codes (all ckt busy) + * + * v1.18 Nenad Corbic + * Added new rel cause support based on + * digits instead of strings. + * + * v1.17 Nenad Corbic + * Added session support + * + * v1.16 Nenad Corbic + * Added hwec disable on loop ccr + * + * v1.15 Nenad Corbic + * Updated DTMF Locking + * Added delay between digits + * + * v1.14 Nenad Corbic + * Updated DTMF Library + * Fixed DTMF synchronization + * + * v1.13 Nenad Corbic + * Woomera OPAL Dialect + * Added Congestion control + * Added SCTP + * Added priority ISUP queue + * Fixed presentation + * + * v1.12 Nenad Corbic + * Fixed CCR + * Removed socket shutdown on end call. + * Let Media thread shutodwn sockets. + * + * v1.11 Nenad Corbic + * Fixed Remote asterisk/woomera connection + * Increased socket timeouts + * + * v1.10 Nenad Corbic + * Added Woomera OPAL dialect. + * Start montor thread in priority + * + * v1.9 Nenad Corbic + * Added Loop mode for ccr + * Added remote debug enable + * Fixed syslog logging. + * + * v1.8 Nenad Corbic + * Added a ccr loop mode for each channel. + * Boost can set any channel in loop mode + * + * v1.7 Nenad Corbic + * Pass trunk group number to incoming call + * chan woomera will use it to append to context + * name. Added presentation feature. + * name. Added presentation feature. + * + * v1.6 Nenad Corbic + * Use only ALAW and MLAW not SLIN. + * This reduces the load quite a bit. + * Send out ALAW/ULAW format on HELLO message. + * RxTx Gain is done now in chan_woomera. + * + * v1.5 Nenad Corbic + * Bug fix in START_NACK_ACK handling. + * When we receive START_NACK we must alwasy pull tank before + * we send out NACK_ACK this way we will not try to send NACK + * ourself. + diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/Changelog.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/Changelog.svn-base deleted file mode 100644 index 385d189..0000000 --- a/ssmg/sangoma_mgd.trunk/.svn/text-base/Changelog.svn-base +++ /dev/null @@ -1,187 +0,0 @@ -sangoma_mgd.c -====================================== -Jun 13 2007 - -v1.13 Nenad Corbic - Woomera OPAL Dialect - Added Congestion control - Added SCTP - Added priority ISUP queue - Fixed presentation - -v1.12 Nenad Corbic - Fixed CCR - Removed socket shutdown on end call. - Let Media thread shutodwn sockets. - -v1.11 Nenad Corbic - Fixed Remote asterisk/woomera connection - Increased socket timeouts - - -chan_woomera.c -====================================== -Jun 13 2007 - -v1.11 Nenad Corbic - Updated multiple profiles - Updated Dialect for OPAL Woomera - Added call logging/debugging - Fixed presentation - -v1.10 Nenad Corbic - Bug fix in incoming hangup - -v1.9 Nenad Corbic - Fixed remote asterisk/woomera - setup. - - -sangoma_mgd.c -====================================== -May 2 2007 - -v1.10 Nenad Corbic - Added Woomera OPAL dialect. - Start montor thread in priority - -v1.9 Nenad Corbic - Added Loop mode for ccr - Added remote debug enable - Fixed syslog logging. - -v1.8 Nenad Corbic - Added a ccr loop mode for each channel. - Boost can set any channel in loop mode - - -chan_woomera.c -===================================== -May 2 2007 - -v1.8 Nenad Corbic - Added Woomera OPAL dialect. - Code cleanup. - Added cli call_status - -v1.7 Nenad Corbic - Added smgdebug to enable smg debugging - Added rdnis - - -sangoma_mgd.c -===================================== -v1.7 Dec 11 2006 - - -Nenad Corbic - -Pass trunk group number to incoming call -chan woomera will use it to append to context -name. - -Added presentation feature. - - -chan_woomera.c -====================================== -v1.6 Dec 11 2006 - -Nenad Corbic - -Added incoming trunk group context -The trunk number will be added to the -profile context name. - -Added presentation feature. - -Added CODING option in woomera.conf to indicate -coding for rx/tx gain on initialization. - - - -sangoma_mgd.c -===================================== -v1.6 Nov 15 2006 - -Nenad Corbic - -Only rx/tx ULAW and ALAW from TDM API. -This greatly reduces system usage, since -two times less traffic passes from -kerel to user space layer. - -The G.711 transcoding is done in asterisk, -there is no benefit in the kernel. - -Removed rxgain/txgain from SMG. - - - -chan_woomera.c -====================================== -v1.5 Nov 15 2006 - -Nenad Corbic - -chan_woomera support for SLINEAR/ULAW/ALAW -voice formats. The codec used is autodetected from SMG. -This option greatly improves system performace -because ulaw/alaw traffic is two times smaller than -SLIN. Resulting in less network traffic. - -Added rxgain and txgain to woomera.conf -Also rxgain and txgain can be globaly changed -from CLI. - -CLI> woomera rxgain 1.0 -CLI> woomera txgain 1.0 - - -sangoma_mgd.c -====================================== -v1.5 Nov 9 2006 - -Nenad Corbic - -Bug fix in START_NACK_ACK handling. ----------------------------------- - -When we receive START_NACK we must alwasy pull tank before -we send out NACK_ACK this way we will not try to send NACK -ourself. - - -New RX/TX Gain options ----------------------- - -In /etc/sangoma_mgd.conf - rxgain=>0 - txgain=>0 - -These optinos can be used to adjust -rx tx gain. Thes options are identical to -zaptel options in zapata.conf. - - - -chan_woomera.c -====================================== -v.1.4 Nov 2006 - -Nenad Corbic - -Added the woomera panic option to gracefully stop -all calls. - -CLI> woomera panic 10 - -This command will completely gracefully stop all calls -and it will disable woomera. - -After this point one can gracefully unload woomera module. - -CLI> unload chan_woomera.so - - - diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/Makefile.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/Makefile.svn-base index adad9f1..9ee014c 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/text-base/Makefile.svn-base +++ b/ssmg/sangoma_mgd.trunk/.svn/text-base/Makefile.svn-base @@ -30,10 +30,11 @@ ifndef KINSTDIR endif CC = gcc +INSTALLPREFIX= INCLUDES = -I$(KDIR)/include -I ../../ssmg/libsangoma.trunk -I. -I ../../patches/kdrivers/include -I ../../patches/kdrivers/wanec/oct6100_api/include -I ../../patches/kdrivers/wanec -I/usr/local/include -I../../patches/kdrivers/include -I/usr/include/wanpipe -Ilib/libteletone/src -CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 +CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm @@ -47,7 +48,7 @@ endif all: sangoma_mgd libs: - $(shell cd lib/libteletone; ./configure; cd ../../; ) + $(shell cd lib/libteletone; ./configure --prefix=$(INSTALLPREFIX); cd ../../; ) $(MAKE) -C lib/libteletone all switch_buffer.o: switch_buffer.c switch_buffer.h @@ -79,23 +80,20 @@ install_smg: old_cleanup @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ install -D -m 755 sangoma_mgd.conf.sample $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ fi +ifeq "${NO_SS7}" "YES" + @echo"SS7 control and service script not installed" +else install -D -m 755 smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/etc/init.d/smgss7_init_ctrl + install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/usr/sbin/smgss7_init_ctrl +endif @echo "sangoma_mgd Installed" old_cleanup: ./scripts/old_cleanup.sh -install_woomera: - install -D -m 755 chan_woomera.so $(INSTALLPREFIX)/usr/lib/asterisk/modules/chan_woomera.so - @if [ ! -e $(INSTALLPREFIX)/etc/asterisk/woomera.conf ]; then \ - install -D -m 755 woomera.conf $(INSTALLPREFIX)/etc/asterisk/woomera.conf; \ - fi - @echo "chan_woomera Installed" - - -install_all: all install_smg install_woomera +install_all: all install_smg uninstall: /bin/rm $(INSTALLPREFIX)/usr/sbin/sangoma_mgd $(INSTALLPREFIX)/etc/sangoma_mgd.conf diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/call_signal.c.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/call_signal.c.svn-base index 3d39f12..5e28542 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/text-base/call_signal.c.svn-base +++ b/ssmg/sangoma_mgd.trunk/.svn/text-base/call_signal.c.svn-base @@ -116,6 +116,9 @@ int call_signal_connection_open(call_signal_connection_t *mcon, char *local_ip, call_signal_event_t *call_signal_connection_read(call_signal_connection_t *mcon, int iteration) { unsigned int fromlen = sizeof(struct sockaddr_in); +#if 0 + call_signal_event_t *event = &mcon->event; +#endif int bytes = 0; bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, @@ -135,6 +138,7 @@ call_signal_event_t *call_signal_connection_read(call_signal_connection_t *mcon, return NULL; } + mcon->txwindow = mcon->txseq - mcon->event.bseqno; mcon->rxseq++; if (mcon->rxseq != mcon->event.fseqno) { @@ -146,8 +150,24 @@ call_signal_event_t *call_signal_connection_read(call_signal_connection_t *mcon, clog_printf(0, mcon->log, "------------------------------------------\n"); } + +#if 0 +/* Debugging only not to be used in production because span/chan can be invalid */ + if (mcon->event.span < 0 || mcon->event.chan < 0 || mcon->event.span > 16 || mcon->event.chan > 31) { + clog_printf(0, mcon->log, + "------------------------------------------\n"); + clog_printf(0, mcon->log, + "Critical Error: RX Cmd=%s Invalid Span=%i Chan=%i\n", + call_signal_event_id_name(event->event_id), event->span,event->chan); + clog_printf(0, mcon->log, + "------------------------------------------\n"); + + errno=EAGAIN; + return NULL; + } +#endif + - mcon->txwindow = mcon->txseq - mcon->event.bseqno; return &mcon->event; @@ -169,6 +189,9 @@ call_signal_event_t *call_signal_connection_read(call_signal_connection_t *mcon, call_signal_event_t *call_signal_connection_readp(call_signal_connection_t *mcon, int iteration) { unsigned int fromlen = sizeof(struct sockaddr_in); +#if 0 + call_signal_event_t *event = &mcon->event; +#endif int bytes = 0; bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, @@ -176,6 +199,23 @@ call_signal_event_t *call_signal_connection_readp(call_signal_connection_t *mcon if (bytes == sizeof(mcon->event) || bytes == (sizeof(mcon->event)-sizeof(uint32_t))) { + +#if 0 + /* Debugging only not to be used in production because span/chan can be invalid */ + if (mcon->event.span < 0 || mcon->event.chan < 0 || mcon->event.span > 16 || mcon->event.chan > 31) { + clog_printf(0, mcon->log, + "------------------------------------------\n"); + clog_printf(0, mcon->log, + "Critical Error: RXp Cmd=%s Invalid Span=%i Chan=%i\n", + call_signal_event_id_name(event->event_id), event->span,event->chan); + clog_printf(0, mcon->log, + "------------------------------------------\n"); + + errno=EAGAIN; + return NULL; + } +#endif + return &mcon->event; } else { if (iteration == 0) { @@ -205,7 +245,7 @@ int call_signal_connection_write(call_signal_connection_t *mcon, call_signal_eve clog_printf(0, mcon->log, "------------------------------------------\n"); clog_printf(0, mcon->log, - "Critical Error: Cmd=%s Invalid Span=%i Chan=%i\n", + "Critical Error: TX Cmd=%s Invalid Span=%i Chan=%i\n", call_signal_event_id_name(event->event_id), event->span,event->chan); clog_printf(0, mcon->log, "------------------------------------------\n"); diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/install.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/install.svn-base index 2a77325..6e48af4 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/text-base/install.svn-base +++ b/ssmg/sangoma_mgd.trunk/.svn/text-base/install.svn-base @@ -6,6 +6,10 @@ force="false" noss7="false" rootdir="" pbxdir=/usr/src/asterisk +pbxd="asterisk" +cfgdir="/etc/asterisk" + + while [ ! -z $1 ] do @@ -17,10 +21,10 @@ do shift pbxdir=$1 if [ "$pbxdir" = "" ]; then - echo "Error: Invalid Asterisk dir: $pbxdir!"; + echo "Error: Invalid $pbxd dir: $pbxdir!"; exit 1 elif [ ! -d $pbxdir ]; then - echo "Error: Asterisk dir does not exist: $pbxdir!"; + echo "Error: $pbxd dir does not exist: $pbxdir!"; exit 1 fi @@ -45,6 +49,16 @@ do shift done +if [ -f $pbxdir/include/callweaver.h ]; then + echo "PBXD=callweaver" > /etc/wanpipe/pbxd + pbxd="callweaver" + cfgdir="/usr/local/etc/callweaver" +else + echo "PBXD=asterisk" > /etc/wanpipe/pbxd + pbxd="asterisk" + cfgdir="/etc/asterisk" +fi + if [ $noss7 != 'true' ]; then if [ ! -e /usr/local/ss7box/$ss7boost ]; then echo "Error: ss7boost not found in /usr/local/ss7box dir"; @@ -176,7 +190,7 @@ eval "make" if [ $? -ne 0 ]; then exit 1; fi -make install +make INSTALLPREFIX=$rootdir install echo "Ok." if [ -d chan_woomera.trunk ]; then @@ -201,15 +215,9 @@ if [ -d chan_woomera.trunk ]; then exit 1; fi - make install + make INSTALLPREFIX=$rootdir install echo "Ok." - if [ -d /etc/asterisk ]; then - if [ ! -f /etc/asterisk/woomera.conf ]; then - \cp -f woomera.conf /etc/asterisk - fi - fi - else echo "Warning: chan_woomera directory does not exist!" exit 1 @@ -225,8 +233,8 @@ echo "--> Start: sangoma_mgd -bg" echo echo " Chan Woomera Install Done" echo -echo "--> Config: /etc/asterisk/woomera.conf" -echo "--> Start: Part of Asterisk (start asterisk)" +echo "--> Config: $cfgdir/woomera.conf" +echo "--> Start: start $pbxd (part of $pbxd)" echo echo "---------------------------------" diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.c.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.c.svn-base index 08a068b..6b9c034 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.c.svn-base +++ b/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.c.svn-base @@ -1,13 +1,49 @@ /********************************************************************************* * sangoma_mgd.c -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards * - * Copyright 05-07, Nenad Corbic + * Copyright 05-08, Nenad Corbic * Anthony Minessale II * * This program is free software, distributed under the terms of * the GNU General Public License * * ============================================= + * v1.26 Nenad Corbic + * Jan 18 2007 + * Fixed hangup after invalid Answer or Ack Session + * Can cause double use of setup id - now fixed + * Update on autoacm on accept check for acked. + * + * v1.25 Nenad Corbic + * Dec 31 2007 + * Removed UDP Resync it can cause skb_over errors. + * Moved RDNIS message to higher debug level + * + * v1.24 Nenad Corbic + * Nov 30 2007 + * Bug fix on return code on ALL ckt busy + * + * v1.23 Nenad Corbic + * Bug fix on socket open. Check for retun code >= 0 + * + * v1.22 Nenad Corbic + * Nov 27 2007 + * Updated DTMF Tx function + * Fixed - dtmf tx without voice + * Fxied - dtmf clipping. + * + * v1.21 Nenad Corbic + * Nov 25 2007 + * Major unit testing of each state + * Numerous bug fixes for non autoacm mode. + * Changed "Channel-Name" to tg/cic + * Added compile option WANPIPE_CHAN_NAME to change Asterisk channel + * name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE}) + * instead of WOOMERA (for example) + * + * v1.20 Nenad Corbic + * Added option for Auto ACM response mode. + * * v1.19 Nenad Corbic * Configurable DTMF * Bug fix in release codes (all ckt busy) @@ -99,7 +135,7 @@ static struct woomera_interface woomera_dead_dev; #endif -#define SMG_VERSION "v1.19" +#define SMG_VERSION "v1.26" /* enable early media */ #if 1 @@ -112,11 +148,9 @@ static struct woomera_interface woomera_dead_dev; #define SMG_DTMF_RATE 8000 #if 0 -#warning "NENAD: MEDIA SHUTDOWN" #define MEDIA_SOCK_SHUTDOWN 1 #endif - #ifdef DOTRACE static int tc = 0; #endif @@ -132,9 +166,11 @@ static int tc = 0; hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; #endif +#undef SMG_CALLING_NAME + const char WELCOME_TEXT[] = "================================================================================\n" -"Sangoma Media Gateway Daemon v1.19 \n" +"Sangoma Media Gateway Daemon v1.26 \n" "TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n" "Copyright 2005, 2006, 2007 \n" "Nenad Corbic , Anthony Minessale II \n" @@ -147,6 +183,7 @@ const char WELCOME_TEXT[] = static int master_reset=0; static int coredump=1; +static int autoacm=1; static int launch_media_tdm_thread(struct woomera_interface *woomera); static int launch_woomera_thread(struct woomera_interface *woomera); @@ -614,7 +651,7 @@ static void add_listener(struct woomera_interface *woomera) } -#ifdef SMG_DTMF_ENABLE + static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) { struct media_session *ms = woomera_get_ms(woomera); @@ -662,7 +699,6 @@ static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) ms->skip_read_frames = 200; return 0; } -#endif static struct woomera_interface *alloc_woomera(void) { @@ -767,6 +803,41 @@ static int waitfor_socket(int fd, int timeout, int flags) return res; } + +static int waitfor_tx_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if (pfds[0].revents & POLLOUT) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + + #else static int waitfor_socket(int fd, int timeout, int flags) @@ -880,7 +951,6 @@ static struct media_session *media_session_new(struct woomera_interface *woomera woomera_set_ms(woomera,ms); ms->woomera = woomera; -#ifdef SMG_DTMF_ENABLE /* Setup artificial DTMF stuff */ memset(&ms->tone_session, 0, sizeof(ms->tone_session)); if (teletone_init_session(&ms->tone_session, 0, NULL, NULL)) { @@ -893,7 +963,6 @@ static struct media_session *media_session_new(struct woomera_interface *woomera ms->tone_session.wait = server.dtmf_off * (ms->tone_session.rate / 1000); teletone_dtmf_detect_init (&ms->dtmf_detect, SMG_DTMF_RATE); -#endif } else { log_printf(0, server.log, "ERROR: Memory Alloc Failed [w%ig%i]!\n", @@ -909,10 +978,8 @@ static void media_session_free(struct media_session *ms) free(ms->ip); } -#ifdef SMG_DTMF_ENABLE teletone_destroy_session(&ms->tone_session); switch_buffer_destroy(&ms->dtmf_buffer); -#endif ms->woomera = NULL; @@ -931,7 +998,7 @@ static int create_udp_socket(struct media_session *ms, char *local_ip, int local memset(&ms->remote_hp, 0, sizeof(ms->remote_hp)); memset(&ms->local_hp, 0, sizeof(ms->local_hp)); - if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0))) { + if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { gethostbyname_r(ip, &ms->remote_hp, buf, sizeof(buf), &result, &err); gethostbyname_r(local_ip, &ms->local_hp, local_buf, sizeof(local_buf), &local_result, &err); if (result && local_result) { @@ -983,7 +1050,7 @@ static int next_media_port(void) return port; } -#ifdef SMG_DTMF_ENABLE + static int woomera_dtmf_transmit(struct media_session *ms, int mtu) { @@ -996,6 +1063,9 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) int slin_len = mtu*2; short *data; int used; + int res; + int err; + int txdtmf=0; memset(&hdrframe,0,sizeof(hdrframe)); if (!ms->dtmf_buffer) { @@ -1003,8 +1073,17 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) } for (;;) { + + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + break; + } -#ifdef CODEC_LAW_DEFAULT + res = waitfor_tx_socket(ms->sangoma_sock, -1, POLLERR | POLLOUT); + if (res <= 0) { + break; + } + +#ifdef CODEC_LAW_DEFAULT pthread_mutex_lock(&woomera->dtmf_lock); if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { @@ -1018,14 +1097,6 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) if (bread <= 0) { break; } - -#if 0 - if (bread < slin_len) { - while (bread < slin_len) { - dtmf[bread++] = 0xFF; - } - } -#endif log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes MTU=%i Coding=%i Used=%i\n", woomera->interface,bread,mtu,ms->hw_coding,used); @@ -1041,24 +1112,23 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) } } - sangoma_sendmsg_socket(ms->sangoma_sock, + err=sangoma_sendmsg_socket(ms->sangoma_sock, &hdrframe, sizeof(hdrframe), dtmf_law, mtu, 0); - - ms->skip_write_frames+=server.dtmf_intr_ch; + + if (err != mtu) { + log_printf(0, woomera->log, "Error: Failed to TX to TDM API on DTMF (err=%i mtu=%i)!\n",err,mtu); + } + + txdtmf++; + ms->skip_write_frames++; #else ... pthread_mutex_lock(&woomera->dtmf_lock); bread = switch_buffer_read(ms->dtmf_buffer, dtmf, mtu); pthread_mutex_unlock(&woomera->dtmf_lock); - if (bread < mtu) { - while (bread < mtu) { - dtmf[bread++] = 0; - } - } - log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes\n", woomera->interface,bread); @@ -1066,14 +1136,18 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) &hdrframe, sizeof(hdrframe), dtmf, mtu, 0); + txdtmf++; ms->skip_write_frames++; #endif - return 0; + } - - return -1; + + if (txdtmf) { + return 0; + } else { + return -1; + } } -#endif static void media_loop_run(struct media_session *ms) { @@ -1246,6 +1320,7 @@ static void *media_thread_run(void *obj) struct woomera_event wevent; wanpipe_tdm_api_t tdm_api; FILE *tx_fd=NULL; + int sock_timeout=200; if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || @@ -1400,7 +1475,7 @@ static void *media_thread_run(void *obj) local_port, WOOMERA_LINE_SEPERATOR, woomera->interface, - WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, WOOMERA_RECORD_SEPERATOR ); #endif @@ -1426,12 +1501,23 @@ static void *media_thread_run(void *obj) while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && !woomera_test_flag(woomera, WFLAG_MEDIA_END) && !woomera_test_flag(woomera, WFLAG_HANGUP) && - (res = waitfor_socket(ms->udp_sock, 1000, POLLERR | POLLIN)) >= 0) { + (res = waitfor_socket(ms->udp_sock, sock_timeout, POLLERR | POLLIN)) >= 0) { unsigned int fromlen = sizeof(struct sockaddr_in); if (res == 0) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + log_printf(4, server.log, "%s: UDP Sock Timeout !!!\n", woomera->interface); /* NENAD Timeout thus just continue */ @@ -1451,6 +1537,8 @@ static void *media_thread_run(void *obj) if (packet_len > 0) { +#if 0 +/* NC: This can cause skb_over panic must be retested */ if (packet_len != sangoma_frame_len && ms->udp_sync_cnt <= 5) { /* Assume that we will always receive SLINEAR here */ sangoma_tdm_set_usr_period(ms->sangoma_sock, @@ -1458,7 +1546,7 @@ static void *media_thread_run(void *obj) sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); - log_printf(0, server.log, + log_printf(3, server.log, "%s: UDP TDM Period ReSync to Len=%i %ims (udp=%i) \n", woomera->interface,sangoma_frame_len, sangoma_frame_len/codec_sample,packet_len); @@ -1475,23 +1563,27 @@ static void *media_thread_run(void *obj) } } - -#ifdef SMG_DTMF_ENABLE - if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { - /* For sanity sake if we are doing the out test - * dont take any chances force tx udp data */ - if (!server.out_tx_test) { +#endif + if (!server.out_tx_test) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + /* For sanity sake if we are doing the out test + * dont take any chances force tx udp data */ if (ms->skip_write_frames > 0) { - ms->skip_write_frames--; + ms->skip_write_frames--; } continue; + } else { + sock_timeout=200; } - } - if (ms->skip_write_frames > 0) { - ms->skip_write_frames--; - continue; - } -#endif + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + continue; + } + + } if (server.out_tx_test && tx_fd && fread((void*)udp_frame, @@ -1799,6 +1891,10 @@ static struct woomera_interface * launch_woomera_loop_thread(call_signal_event_t } woomera_set_interface(woomera,callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = woomera; + pthread_mutex_unlock(&server.process_lock); if (launch_woomera_thread(woomera)) { pthread_mutex_lock(&server.process_lock); @@ -1878,10 +1974,12 @@ static int woomera_message_parse(struct woomera_interface *woomera, struct woome } ysleep(1000); continue; + } else if (res < 0) { log_printf(3, woomera->log, WOOMERA_DEBUG_PREFIX - "%s error during packet retry #%d\n", - woomera->interface, loops); + "%s error during packet retry (err=%i) Loops#%d (%s)\n", + woomera->interface, res, loops, + strerror(errno)); return res; } else if (loops) { ysleep(100000); @@ -2024,8 +2122,10 @@ static struct woomera_interface *pull_from_holding_tank(int index, int span , in struct woomera_interface *woomera = NULL; if (index < 1 || index >= CORE_TANK_LEN) { - log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", - __FUNCTION__,index); + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } return NULL; } @@ -2047,18 +2147,25 @@ static struct woomera_interface *pull_from_holding_tank(int index, int span , in return woomera; } -static void clear_from_holding_tank(int index) +static void clear_from_holding_tank(int index, struct woomera_interface *woomera) { if (index < 1 || index >= CORE_TANK_LEN) { - log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", - __FUNCTION__,index); + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } return; } pthread_mutex_lock(&server.ht_lock); if (server.holding_tank[index] == &woomera_dead_dev) { - server.holding_tank[index] = NULL; + server.holding_tank[index] = NULL; + } else if (woomera && server.holding_tank[index] == woomera) { + server.holding_tank[index] = NULL; + } else if (server.holding_tank[index]) { + log_printf(0, server.log, "Error: Holding tank index %i not cleared %p !\n", + index, server.holding_tank[index]); } pthread_mutex_unlock(&server.ht_lock); @@ -2070,8 +2177,10 @@ static struct woomera_interface *peek_from_holding_tank(int index) struct woomera_interface *woomera = NULL; if (index < 1 || index >= CORE_TANK_LEN) { - log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", - __FUNCTION__,index); + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } return NULL; } @@ -2117,7 +2226,7 @@ static int add_to_holding_tank(struct woomera_interface *woomera) log_printf(0, server.log, "\nCritical Error failed to obtain a TANK INDEX\n"); return 0; } - + server.holding_tank[next] = woomera; woomera->timeout = time(NULL) + 100; @@ -2164,6 +2273,7 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, log_printf(4, server.log,"ERROR: Failed to Launch Call [%s]\n", woomera->interface); +#if 0 new_woomera_event_printf(&wevent, "501 call was cancelled!%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2171,7 +2281,7 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - +#endif new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id: %s%s" @@ -2202,6 +2312,18 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); } else { + + if (accept) { + if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + } + if (answer) { struct media_session *ms; @@ -2212,6 +2334,16 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, pthread_mutex_unlock(&woomera->ms_lock); if (ms) { + + if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + isup_exec_command(woomera->span, woomera->chan, -1, @@ -2262,27 +2394,38 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - } + } - return 0; + return 0; } -static int handle_woomera_call_start (struct woomera_interface *woomera, - struct woomera_message *wmsg) +static int handle_woomera_call_start (struct woomera_interface *woomera, + struct woomera_message *wmsg) { - char *raw = woomera_message_header(wmsg, "raw-audio"); - call_signal_event_t event; - char *calling = woomera_message_header(wmsg, "local-number"); + char *raw = woomera_message_header(wmsg, "raw-audio"); + call_signal_event_t event; + char *calling = woomera_message_header(wmsg, "local-number"); +#ifdef SMG_CALLING_NAME + char *calling_name = woomera_message_header(wmsg, "local-name"); +#endif char *presentation = woomera_message_header(wmsg, "Presentation"); char *screening = woomera_message_header(wmsg, "Screening"); char *rdnis = woomera_message_header(wmsg, "RDNIS"); - //char *callerid = woomera_message_header(wmsg, "local-name"); char *called = wmsg->callid; char *grp = wmsg->callid; char *p; + int cause = 34; int tg = 0; if (smg_check_all_busy()) { + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); socket_printf(woomera->socket, "405 SMG Server All Ckt Busy!%s", WOOMERA_RECORD_SEPERATOR); log_printf(3, woomera->log, "SMG Server Full %d (ckt busy cnt=%i)\n", @@ -2301,12 +2444,22 @@ static int handle_woomera_call_start (struct woomera_interface *woomera, } } + woomera->trunk_group=tg; + if (raw) { woomera_set_raw(woomera, raw); } woomera->index = add_to_holding_tank(woomera); if (woomera->index < 1) { + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); socket_printf(woomera->socket, "405 SMG Server All Tanks Busy!%s", WOOMERA_RECORD_SEPERATOR); @@ -2335,16 +2488,34 @@ static int handle_woomera_call_start (struct woomera_interface *woomera, if (rdnis && strlen(rdnis)) { strncpy((char*)event.redirection_string,rdnis, sizeof(event.redirection_string)-1); - log_printf(0,server.log,"RDNIS %s\n", rdnis); + log_printf(3,server.log,"RDNIS %s\n", rdnis); } +#ifdef SMG_CALLING_NAME + if (calling_name) { + strncpy((char*)event.calling_name,calling_name, + sizeof(event.calling_name)-1); + } +#endif + event.trunk_group = tg; + if (call_signal_connection_write(&server.mcon, &event) <= 0) { log_printf(0, server.log, "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", strerror(errno)); + + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "405 SMG Signalling Contestion!%s", WOOMERA_RECORD_SEPERATOR); @@ -2364,6 +2535,8 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ { int answer = 0, media = 0, accept=0; char *unique_id; + int cause=0; + if (!strcasecmp(wmsg->command, "call")) { @@ -2378,8 +2551,9 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ err=handle_woomera_call_start(woomera,wmsg); if (err) { - woomera_clear_flag(woomera, WFLAG_RUNNING); + woomera_set_flag(woomera, WFLAG_HANGUP); } + return; } else if (!strcasecmp(wmsg->command, "bye") || !strcasecmp(wmsg->command, "quit")) { @@ -2453,15 +2627,24 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ return; } + unique_id = woomera_message_header(wmsg, "Unique-Call-Id"); if (!unique_id) { - socket_printf(woomera->socket, "400 Error no unique id found %s", - WOOMERA_RECORD_SEPERATOR); - log_printf(0,server.log,"Woomera RX Even (%s) without unique id!\n",wmsg->command); - if (!strcasecmp(wmsg->command, "hangup")) { - woomera_clear_flag(woomera, WFLAG_RUNNING); - } + cause=111; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "400 Woomera cmd without uniquie id%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2,server.log,"Woomera RX Event (%s) without unique id!\n",wmsg->command); + woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2479,15 +2662,24 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ "WOOMERA Got CMD %s Span=%d Chan=%d from session %s\n", wmsg->command,span,chan,unique_id); - if (smg_validate_span_chan(span,chan) != 0) { - socket_printf(woomera->socket, - "400 Error invalid span chan in session! %s", + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Invalid span/chan in session%s" WOOMERA_RECORD_SEPERATOR); - - log_printf(0, woomera->log, - "WOOMERA Error invalid span chan in session %s\n", + + log_printf(2, woomera->log, + "WOOMERA Warning invalid span chan in session %s %s\n", wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2498,11 +2690,22 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ if (session_woomera) { pthread_mutex_unlock(&server.process_lock); - socket_printf(woomera->socket, "400 Error channel in use! %s", + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Session not found%s" WOOMERA_RECORD_SEPERATOR); + - log_printf(0, woomera->log, "WOOMERA Error channel in use %s\n", + log_printf(0, woomera->log, "WOOMERA Error channel in use %s %s\n", wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2510,11 +2713,23 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ strncmp(session,unique_id,sizeof(woomera->session))){ pthread_mutex_unlock(&server.process_lock); - socket_printf(woomera->socket, "400 Error no such session %s", + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Invalid/Expired Session%s" WOOMERA_RECORD_SEPERATOR); - log_printf(0, woomera->log, + + log_printf(3, woomera->log, "WOOMERA Warning: Cmd=%s with invalid session %s (orig=%s)\n", wmsg->command,unique_id,session?session:"N/A"); + woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2534,20 +2749,31 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ } else if (strncmp(woomera->session,unique_id,sizeof(woomera->session))) { - socket_printf(woomera->socket, "400 Error session missmatch %s", + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Session Mis-match%s" WOOMERA_RECORD_SEPERATOR); + woomera_set_flag(woomera, WFLAG_HANGUP); return; } - + if (!strcasecmp(wmsg->command, "dtmf")) { log_printf(3, woomera->log, "WOOMERA CMD: DTMF Received: [%s] Digit %s Body %s\n", woomera->interface, wmsg->command_args, wmsg->body); -#ifdef SMG_DTMF_ENABLE wanpipe_send_dtmf(woomera,wmsg->body); -#endif + socket_printf(woomera->socket, "200 DTMF OK%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2573,6 +2799,7 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ woomera->interface,cause); if (smg_validate_span_chan(span,chan) != 0) { + socket_printf(woomera->socket, "405 No Such Channel%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2650,13 +2877,20 @@ static void handle_call_answer(call_signal_event_t *event) woomera = server.process_table[event->span][event->chan].dev; pthread_mutex_unlock(&server.process_lock); - if (woomera && woomera->raw) { + if (woomera) { char callid[80]; struct woomera_event wevent; + if (!woomera->raw) { + log_printf(1, server.log, "Refusing to answer call with no media!\n"); + kill++; + goto handle_call_answer_end; + } + if (woomera_test_flag(woomera, WFLAG_ANSWER)) { log_printf(1, server.log, "Refusing to double-answer a call!\n"); - return; + kill++; + goto handle_call_answer_end; } woomera_set_flag(woomera, WFLAG_ANSWER); @@ -2664,7 +2898,7 @@ static void handle_call_answer(call_signal_event_t *event) if (woomera->span != event->span || woomera->chan != event->chan) { log_printf(1, server.log, "Refusing to start media on a different channel from the one we agreed on.!\n"); kill++; - return; + goto handle_call_answer_end; } if (woomera_test_flag(woomera, WFLAG_HANGUP)) { @@ -2680,6 +2914,7 @@ static void handle_call_answer(call_signal_event_t *event) if (err) { log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", woomera->interface); +#if 0 new_woomera_event_printf(&wevent, "501 call was cancelled!%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2687,7 +2922,8 @@ static void handle_call_answer(call_signal_event_t *event) WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - +#endif + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id: %s%s" "Q931-Cause-Code: %d%s" @@ -2706,9 +2942,6 @@ static void handle_call_answer(call_signal_event_t *event) - woomera_set_flag(woomera, - (WFLAG_HANGUP|WFLAG_MEDIA_END)); - woomera_clear_flag(woomera, WFLAG_RUNNING); kill++; } #endif @@ -2731,30 +2964,22 @@ static void handle_call_answer(call_signal_event_t *event) kill++; } -#if 0 +handle_call_answer_end: + if (kill) { - call_signal_event_t oevent; - if (woomera) { - if (woomera_test_flag(woomera, WFLAG_HANGUP)) { - /* Do not hangup if this call was already hungup */ - return; - } - - woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_set_flag(woomera,WFLAG_MEDIA_END); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(1, server.log, "Sent CALL STOP to Answer without session [w%dg%d]\n", + event->span+1, event->chan+1); } - - isup_exec_command(event->span, - event->chan, - -1, - SIGBOOST_EVENT_CALL_STOPPED, - SIGBOOST_RELEASE_CAUSE_NORMAL); - - log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", - event->span+1, event->chan+1); } -#endif - } static void handle_call_start_ack(call_signal_event_t *event) @@ -2763,7 +2988,7 @@ static void handle_call_start_ack(call_signal_event_t *event) struct woomera_event wevent; int kill = 0; - if ((woomera = pull_from_holding_tank(event->call_setup_id,event->span,event->chan))) { + if ((woomera = peek_from_holding_tank(event->call_setup_id))) { char callid[80]; if (woomera_test_flag(woomera, WFLAG_HANGUP)) { @@ -2771,11 +2996,14 @@ static void handle_call_start_ack(call_signal_event_t *event) kill++; } else { int err, span, chan; + + pull_from_holding_tank(event->call_setup_id,event->span,event->chan); sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); span = event->span; chan = event->chan; + woomera_set_flag(woomera,WFLAG_CALL_ACKED); woomera_set_interface(woomera, callid); pthread_mutex_lock(&server.process_lock); @@ -2793,6 +3021,8 @@ static void handle_call_start_ack(call_signal_event_t *event) log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", woomera->interface); + +#if 0 new_woomera_event_printf(&wevent, "501 call was cancelled!%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2800,7 +3030,8 @@ static void handle_call_start_ack(call_signal_event_t *event) WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - +#endif + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id:%s%s" "Q931-Cause-Code: %d%s" @@ -2816,9 +3047,7 @@ static void handle_call_start_ack(call_signal_event_t *event) ); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - - woomera_set_flag(woomera,WFLAG_MEDIA_END); - woomera_clear_flag(woomera, WFLAG_RUNNING); + kill++; } #endif @@ -2832,10 +3061,14 @@ static void handle_call_start_ack(call_signal_event_t *event) enqueue_event(woomera, &wevent,EVENT_FREE_DATA); new_woomera_event_printf(&wevent, "EVENT PROCEED w%dg%d%s" + "Channel-Name: g%d/%d%s" "Unique-Call-Id: %s%s", event->span+1, event->chan+1, WOOMERA_LINE_SEPERATOR, + woomera->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, woomera->session, WOOMERA_RECORD_SEPERATOR ); @@ -2853,30 +3086,20 @@ static void handle_call_start_ack(call_signal_event_t *event) kill++; } -#if 0 if (kill) { - call_signal_event_t oevent; - if (woomera) { - if (woomera_test_flag(woomera, WFLAG_HANGUP)) { - /* Do not hangup if this call was already hungup */ - return; - } - - woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_set_flag(woomera,WFLAG_MEDIA_END); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(1, server.log, "Sent CALL STOP to CALL START ACK without session [w%dg%d]\n", + event->span+1, event->chan+1); } - - isup_exec_command(event->span, - event->chan, - -1, - SIGBOOST_EVENT_CALL_STOPPED, - SIGBOOST_RELEASE_CAUSE_NORMAL); - - log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", - event->span+1, event->chan+1); } -#endif - } static void handle_call_start_nack(call_signal_event_t *event) @@ -2897,37 +3120,21 @@ static void handle_call_start_nack(call_signal_event_t *event) } if (event->call_setup_id > 0) { - woomera=pull_from_holding_tank(event->call_setup_id,-1,-1); + woomera=peek_from_holding_tank(event->call_setup_id); } if (woomera) { struct woomera_event wevent; - woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); - woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); - isup_exec_command(0, - 0, - event->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0); - - - if (woomera_test_flag(woomera, WFLAG_HANGUP)) { log_printf(0, server.log, "Event CALL START NACK on hungup call [%d]!\n", event->call_setup_id); + ack++; } else { - woomera_set_cause_topbx(woomera,event->release_cause); - - new_woomera_event_printf(&wevent, "501 Error!%s" - "Unique-Call-Id: %s%s", - WOOMERA_LINE_SEPERATOR, - woomera->session, - WOOMERA_RECORD_SEPERATOR); - - enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + woomera_set_cause_topbx(woomera,event->release_cause); + woomera_set_flag(woomera, (WFLAG_HANGUP|WFLAG_HANGUP_NACK_ACK)); new_woomera_event_printf(&wevent, "EVENT HANGUP w%dg%d%s" "Unique-Call-Id: %s%s" @@ -2945,55 +3152,58 @@ static void handle_call_start_nack(call_signal_event_t *event) ); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + woomera_set_flag(woomera, WFLAG_HANGUP); woomera_clear_flag(woomera, WFLAG_RUNNING); + /* Do not ack here, let woomera thread ack it */ + ack=0; } - - /* We already did the NACK */ - ack=0; + } else if (event->call_setup_id == 0 && smg_validate_span_chan(event->span,event->chan) == 0) { pthread_mutex_lock(&server.process_lock); woomera = server.process_table[event->span][event->chan].dev; - server.process_table[event->span][event->chan].dev=NULL; + + if (woomera) { + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } else if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* At this point call is already hang up */ + woomera=NULL; + } else { + /* At this point call is already hang up */ + woomera=NULL; + } + } + memset(server.process_table[event->span][event->chan].session, 0,SMG_SESSION_NAME_SZ); pthread_mutex_unlock(&server.process_lock); + if (woomera) { - log_printf(0, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", + log_printf(2, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", woomera->span+1,woomera->chan+1,woomera,woomera->ms); - - woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); - woomera_set_flag(woomera, - (WFLAG_HANGUP|WFLAG_MEDIA_END)); - isup_exec_command(event->span, - event->chan, - event->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0); - -#ifdef MEDIA_SOCK_SHUTDOWN - pthread_mutex_lock(&woomera->ms_lock); - if (woomera->ms) { - shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); - shutdown(woomera->ms->udp_sock, SHUT_RDWR); + if (!woomera_test_flag(woomera,WFLAG_HANGUP)){ + woomera_set_cause_topbx(woomera,event->release_cause); } - pthread_mutex_unlock(&woomera->ms_lock); -#endif - - /* We already did the NACK */ + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END|WFLAG_HANGUP_NACK_ACK)); + + /* Nack Ack will be sent by the woomera thread */ ack=0; } else { - + /* Valid state when we are not in autoacm mode */ ack++; - log_printf(0, server.log, "Error: No Device on valid Span Chan [w%dg%d]!\n", + log_printf(3, server.log, "Event: NACK no woomera on span chan [w%dg%d]!\n", event->span+1, event->chan+1); } @@ -3003,12 +3213,14 @@ static void handle_call_start_nack(call_signal_event_t *event) event->call_setup_id, event->span+1, event->chan+1); ack++; } - + + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { log_printf(0, server.log, "WARNING: All ckt busy!\n"); smg_all_ckt_busy(); } + #warning "Ignoring CALL GAP" #if 0 if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP) { @@ -3024,26 +3236,29 @@ static void handle_call_start_nack(call_signal_event_t *event) span=event->span; chan=event->chan; } + isup_exec_command(span, chan, event->call_setup_id, SIGBOOST_EVENT_CALL_START_NACK_ACK, 0); - + if (!woomera) { log_printf(2, server.log, "Event (NACK ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", event->event_id,event->call_setup_id, event->span+1, event->chan+1); + } } } static void handle_call_loop_start(call_signal_event_t *event) { - struct woomera_interface *woomera; + char callid[20]; + char *session; pthread_mutex_lock(&server.process_lock); if (server.process_table[event->span][event->chan].dev) { - + isup_exec_command(event->span, event->chan, -1, @@ -3059,7 +3274,14 @@ static void handle_call_loop_start(call_signal_event_t *event) return; } - pthread_mutex_unlock(&server.process_lock); + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + woomera=launch_woomera_loop_thread(event); if (woomera == NULL) { @@ -3073,6 +3295,7 @@ static void handle_call_loop_start(call_signal_event_t *event) event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); } + woomera_set_flag(woomera,WFLAG_CALL_ACKED); return; } @@ -3084,6 +3307,7 @@ static void handle_call_start(call_signal_event_t *event) char *session; pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { isup_exec_command(event->span, @@ -3099,7 +3323,6 @@ static void handle_call_start(call_signal_event_t *event) pthread_mutex_unlock(&server.process_lock); return; - } sprintf(callid, "w%dg%d", event->span+1,event->chan+1); @@ -3109,13 +3332,13 @@ static void handle_call_start(call_signal_event_t *event) server.process_table[event->span][event->chan].dev = NULL; pthread_mutex_unlock(&server.process_lock); - - isup_exec_command(event->span, - event->chan, - -1, - SIGBOOST_EVENT_CALL_START_ACK, - 0); - + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } new_woomera_event_printf(&wevent, "EVENT INCOMING w%dg%d%s" "Unique-Call-Id: %s%s" @@ -3124,7 +3347,7 @@ static void handle_call_start(call_signal_event_t *event) "Protocol: SS7%s" "User-Agent: sangoma_mgd%s" "Local-Number: %s%s" - "Channel-Name: SMG-g%ds%dc%d%s" + "Channel-Name: g%d/%d%s" "Trunk-Group: %d%s" "Presentation: %d%s" "Screening: %d%s" @@ -3137,15 +3360,18 @@ static void handle_call_start(call_signal_event_t *event) WOOMERA_LINE_SEPERATOR, event->calling_number_digits, WOOMERA_LINE_SEPERATOR, +#ifdef SMG_CALLING_NAME + event->calling_name, +#else "", +#endif WOOMERA_LINE_SEPERATOR, WOOMERA_LINE_SEPERATOR, WOOMERA_LINE_SEPERATOR, event->called_number_digits, WOOMERA_LINE_SEPERATOR, event->trunk_group+1, - event->span+1, - event->chan+1, + (event->span*31)+event->chan+1, WOOMERA_LINE_SEPERATOR, event->trunk_group+1, WOOMERA_LINE_SEPERATOR, @@ -3166,12 +3392,19 @@ static void handle_call_start(call_signal_event_t *event) memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); pthread_mutex_unlock(&server.process_lock); - - isup_exec_command(event->span, - event->chan, - -1, - SIGBOOST_EVENT_CALL_STOPPED, - SIGBOOST_RELEASE_CAUSE_BUSY); + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_BUSY); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + } log_printf(0, server.log, "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", @@ -3197,42 +3430,45 @@ static void handle_restart_ack(call_signal_connection_t *mcon,call_signal_event_ static void handle_call_stop(call_signal_event_t *event) { struct woomera_interface *woomera; - + int ack=0; + pthread_mutex_lock(&server.process_lock); woomera = server.process_table[event->span][event->chan].dev; - server.process_table[event->span][event->chan].dev=NULL; + if (woomera) { + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } else if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* At this point call is already hangup */ + woomera=NULL; + } else { + /* At this point call is already hangup */ + woomera=NULL; + } + } memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); pthread_mutex_unlock(&server.process_lock); if (woomera) { - + woomera_set_cause_topbx(woomera,event->release_cause); + + woomera_set_flag(woomera, + (WFLAG_MEDIA_END|WFLAG_HANGUP|WFLAG_HANGUP_ACK)); - woomera_set_flag(woomera, - (WFLAG_MEDIA_END|WFLAG_HANGUP)); - - woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); - - isup_exec_command(event->span, - event->chan, - -1, - SIGBOOST_EVENT_CALL_STOPPED_ACK, - 0); - -#ifdef MEDIA_SOCK_SHUTDOWN - pthread_mutex_lock(&woomera->ms_lock); - if (woomera->ms) { - shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); - shutdown(woomera->ms->udp_sock, SHUT_RDWR); - } - pthread_mutex_unlock(&woomera->ms_lock); -#endif + /* We have to close the socket because + At this point we are release span chan */ log_printf(3, server.log, "Event CALL STOP on w%dg%d ptr=%p ms=%p\n", woomera->span+1,woomera->chan+1,woomera,woomera->ms); } else { - + ack++; + } + + + if (ack) { /* At this point we have already sent our STOP so its safe to ACK */ isup_exec_command(event->span, event->chan, @@ -3291,6 +3527,7 @@ static void handle_call_stop_ack(call_signal_event_t *event) return; } + static void handle_call_start_nack_ack(call_signal_event_t *event) { @@ -3300,17 +3537,33 @@ static void handle_call_start_nack_ack(call_signal_event_t *event) woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + } else { + log_printf(0, server.log, + "Event NACK ACK [w%dg%d] with valid span/chan no dev!\n", + event->span+1, event->chan+1); + } + } else { log_printf(2, server.log, "Event NACK ACK referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", event->span+1, event->chan+1, event->call_setup_id); } -#if 1 if (event->call_setup_id > 0) { - clear_from_holding_tank(event->call_setup_id); + clear_from_holding_tank(event->call_setup_id, NULL); } -#endif /* No need for us to do any thing here */ return; @@ -3615,6 +3868,8 @@ static void woomera_loop_thread_run(struct woomera_interface *woomera) continue; } + + woomera_clear_flag(woomera, WFLAG_RUNNING); log_printf(2, server.log, "Woomera Session: For Loop Test exiting %s\n",woomera->interface); @@ -3638,8 +3893,8 @@ static void *woomera_thread_run(void *obj) //smg_get_current_priority(&policy,&priority); - log_printf(2, server.log, "WOOMERA session for started (ptr=%p : loop=%i)(%i:%i)\n", - woomera,woomera->loop_tdm,policy,priority); + log_printf(2, server.log, "WOOMERA session started (ptr=%p : loop=%i)(%i:%i) Index=%i\n", + woomera,woomera->loop_tdm,policy,priority, woomera->index); pthread_mutex_lock(&server.thread_count_lock); server.thread_count++; @@ -3715,7 +3970,7 @@ static void *woomera_thread_run(void *obj) "WOOMERA session (ptr=%p) Call Timedout ! [%s] (Timeout=%d)\n", woomera,woomera->interface,woomera->timeout); - /* NENAD Let the Index check run a nak */ + /* Let the Index check below send a NACK */ if (woomera->index) { woomera_set_flag(woomera, WFLAG_HANGUP); } @@ -3761,21 +4016,38 @@ woomera_session_close: /* The call was not HUNGUP. This is the last check, If the call is valid, hungup the call if the call was never up the keep going */ - woomera_set_flag(woomera, WFLAG_HANGUP); + if (smg_validate_span_chan(span,chan) == 0) { if (!woomera->index) { - woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); - isup_exec_command(span, - chan, - -1, - SIGBOOST_EVENT_CALL_STOPPED, - woomera->q931_rel_cause_tosig); - - log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] ptr=%p\n", - span+1, chan+1,woomera->interface,woomera); + if (autoacm || woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + woomera->q931_rel_cause_tosig); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT); + + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } else { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + woomera->q931_rel_cause_tosig); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT); + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_START_NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } } else { log_printf(0, woomera->log, "Woomera Not Sent CALL STOPPED - Instead NACK [w%dg%d] [%s] ptr=%p\n", span+1, chan+1,woomera->interface,woomera); @@ -3785,15 +4057,19 @@ woomera_session_close: /* This can happend if an outgoing call times out or gets hungup before it gets acked. Its not a failure */ + if (!woomera->index) { - log_printf(3, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", + /* In this case we really failed to tx STOP */ + log_printf(0, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", span+1, chan+1, woomera->interface, woomera->index, woomera); + } } - + + woomera_set_flag(woomera, WFLAG_HANGUP); + } woo_re_hangup: - /* We must send a STOP ACK to boost telling it that we are done */ if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { @@ -3824,7 +4100,7 @@ woo_re_hangup: } woomera_clear_flag(woomera, WFLAG_HANGUP_ACK); - + woomera_set_flag(woomera, WFLAG_HANGUP); } if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { @@ -3846,7 +4122,17 @@ woo_re_hangup: "Sent (Nack Ack) to SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] ptr=%p\n", span+1,chan+1,woomera->interface,woomera); - + woomera->index=0; + + } else if (woomera->index) { + isup_exec_command(0, + 0, + woomera->index, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + woomera->index=0; + } else { log_printf(0, woomera->log, "FAILED: Sent (Nack Ack) SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", @@ -3860,8 +4146,7 @@ woo_re_hangup: if (woomera->index) { int index = woomera->index; - int timeout_cnt=0; - int overall_cnt=0; + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id: %s%s" @@ -3887,58 +4172,68 @@ woo_re_hangup: } if (peek_from_holding_tank(index)) { - + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); isup_exec_command(0, 0, index, SIGBOOST_EVENT_CALL_START_NACK, 0); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT); log_printf(2, woomera->log, "Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] .. WAITING FOR NACK ACK\n", index); - - /* SMG sent NACK to boost, however we have to wait - for boost to give us the ACK back before we - release resources. */ - - while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { - timeout_cnt++; - if (timeout_cnt > 40000) { //10sec timeout - timeout_cnt=0; - overall_cnt++; - log_printf(0, woomera->log, - "Waiting for NACK ACK [Setup ID: %d] ... \n", - index); - } - - if (overall_cnt > 10) { //100sec timeotu - woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); - break; - } - - if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { - break; - } - - usleep(5000); - sched_yield(); - } - - if (overall_cnt > 10) { + } else { + log_printf(1, woomera->log, + "Error Failed to Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] - index stale!\n", + index); + } + } + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent NACK to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //30sec timeout + timeout_cnt=0; + overall_cnt++; log_printf(0, woomera->log, - "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", - index); - - } else { - log_printf(2, woomera->log, - "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", - index); + "Waiting for NACK ACK [Setup ID: %d] ... \n", + woomera->index); + } + if (overall_cnt > 10) { //300sec timeotu + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + break; } + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { + break; + } + + usleep(5000); + sched_yield(); } + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", + index); + + } else { + log_printf(2, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", + index); + + } } if (woomera_test_flag(woomera, WFLAG_EVENT)){ @@ -3964,7 +4259,7 @@ woo_re_hangup: while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { timeout_cnt++; - if (timeout_cnt > 40000) { //10sec timeout + if (timeout_cnt > 4000) { //10sec timeout timeout_cnt=0; overall_cnt++; log_printf(0, woomera->log, @@ -3987,18 +4282,18 @@ woo_re_hangup: usleep(5000); sched_yield(); } + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); - if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { - if (overall_cnt > 10) { - log_printf(0, woomera->log, - "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", - woomera->interface,woomera->index_hold); + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); - } else { - log_printf(2, woomera->log, - "Wait GOT STOPPED ACK [%s] [id=%i]... \n", - woomera->interface,woomera->index_hold); - } + } else { + log_printf(2, woomera->log, + "Wait GOT STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); } } @@ -4058,7 +4353,7 @@ woo_re_hangup: * value until the end of the call. Tank is only * used on outgoing calls. */ if (woomera->index_hold >= 1) { - clear_from_holding_tank(woomera->index_hold); + clear_from_holding_tank(woomera->index_hold, woomera); woomera->index_hold=0; } @@ -4282,6 +4577,12 @@ static int configure_server(void) if (max > 0) { server.max_calls = max; } + } else if (!strcasecmp(var, "autoacm")) { + int max = atoi(val); + if (max >= 0) { + autoacm=max; + } + } else if (!strcasecmp(var, "media_ip")) { strncpy(server.media_ip, val, sizeof(server.media_ip) -1); } else { @@ -4297,7 +4598,7 @@ static int configure_server(void) server.dtmf_off=SMG_DTMF_OFF; } if (server.dtmf_intr_ch == -1) { - server.dtmf_intr_ch = server.dtmf_on/server.dtmf_off; + server.dtmf_intr_ch = 0; } server.dtmf_size=(server.dtmf_on+server.dtmf_off)*10*2; @@ -4625,7 +4926,7 @@ static int woomera_startup(int argc, char **argv) } fprintf(stderr, "%s", WELCOME_TEXT); - log_printf(0, stderr, "Woomera STARTUP Complete.\n"); + log_printf(0, stderr, "Woomera STARTUP Complete. [AutoACM=%i]\n",autoacm); return 1; } diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.conf.sample.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.conf.sample.svn-base index 12f131b..0f71566 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.conf.sample.svn-base +++ b/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.conf.sample.svn-base @@ -52,3 +52,10 @@ dtmf_off_duration => 10 #on configuration. Default chunk size #is 10ms. #dtmf_inter_ch_duration => 0 + +#Enable/Disable Auto ISUP ACM +#response to an incoming ss7 call. +#0-Disable +#1-Enable (Default) +autoacm => 1 + diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.h.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.h.svn-base index d0b5319..a938601 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.h.svn-base +++ b/ssmg/sangoma_mgd.trunk/.svn/text-base/sangoma_mgd.h.svn-base @@ -40,21 +40,16 @@ #include #endif -/* Enable DTMF encoding by default */ -#ifndef SMG_DTMF_ENABLE -#define SMG_DTMF_ENABLE 1 -#endif -#ifdef SMG_DTMF_ENABLE #include #include -#endif #define WOOMERA_MAX_SPAN 16 #define WOOMERA_MAX_CHAN 31 #define SMG_SESSION_NAME_SZ 100 +#define SMG_CHAN_NAME_SZ 20 #define PIDFILE "/var/run/sangoma_mgd.pid" #define CORE_EVENT_LEN 512 @@ -95,6 +90,9 @@ typedef enum { WFLAG_WAIT_FOR_NACK_ACK = (1 << 13), WFLAG_WAIT_FOR_STOPPED_ACK = (1 << 14), WFLAG_RAW_MEDIA_STARTED = (1 << 15), + WFLAG_CALL_ACKED = (1 << 16), + WFLAG_WAIT_FOR_NACK_ACK_SENT = (1 << 17), + WFLAG_WAIT_FOR_STOPPED_ACK_SENT = (1 << 18), } WFLAGS; typedef enum { @@ -169,11 +167,9 @@ struct media_session { hp_tdm_api_chan_t *tdmchan; #endif -#ifdef SMG_DTMF_ENABLE teletone_dtmf_detect_state_t dtmf_detect; teletone_generation_session_t tone_session; switch_buffer_t *dtmf_buffer; -#endif }; @@ -224,6 +220,7 @@ struct woomera_interface { int index_hold; int span; int chan; + int trunk_group; int call_count; int q931_rel_cause_tosig; int q931_rel_cause_topbx; @@ -349,7 +346,16 @@ static inline int smg_check_all_busy(void) static inline void smg_all_ckt_busy(void) { - server.all_ckt_busy+=1000; + + if (server.call_count*10 < 1500) { + server.all_ckt_busy+=1500; + } else { + server.all_ckt_busy+=server.call_count*15; + } + + if (server.all_ckt_busy > 60000) { + server.all_ckt_busy = 60000; + } #if 0 if (server.all_ckt_busy >= 5) { @@ -530,6 +536,10 @@ static inline void woomera_set_cause_topbx(struct woomera_interface *woomera, in cause=SIGBOOST_RELEASE_CAUSE_NORMAL; } + if (cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { + cause=34; + } + woomera->q931_rel_cause_topbx=cause; } diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/sigboost.h.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/sigboost.h.svn-base index 5d64154..009e4b2 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/text-base/sigboost.h.svn-base +++ b/ssmg/sangoma_mgd.trunk/.svn/text-base/sigboost.h.svn-base @@ -59,6 +59,7 @@ enum e_sigboost_call_setup_ack_nack_cause_values }; #define MAX_DIALED_DIGITS 31 +#define MAX_CALLING_NAME 31 /* Next two defines are used to create the range of values for call_setup_id * in the t_sigboost structure. diff --git a/ssmg/sangoma_mgd.trunk/.svn/text-base/smg_ctrl.svn-base b/ssmg/sangoma_mgd.trunk/.svn/text-base/smg_ctrl.svn-base index 01f181b..7f7d188 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/text-base/smg_ctrl.svn-base +++ b/ssmg/sangoma_mgd.trunk/.svn/text-base/smg_ctrl.svn-base @@ -31,10 +31,8 @@ function stop_all() else echo "$sigd not running..." fi - if [ $(pidof $sigd) ]; then - echo "Error: failed to stop $sigd...exiting" - exit 1 - fi + + eval "kill -KILL $(pidof $sigd) 2>/dev/null >/dev/null" #stop sangoma media gateway if [ $(pidof sangoma_mgd) ]; then @@ -50,6 +48,8 @@ function stop_all() else echo "sangoma_mgd not running..." fi + + eval "kill -KILL $(pidof sangoma_mgd) 2>/dev/null >/dev/null" } function start_all() diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.3.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.3.tmp new file mode 100644 index 0000000..c8d853a --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.3.tmp @@ -0,0 +1,98 @@ +################################################################################ +# Sangoma MGD +# +# Author: Anthony Minessale II +# Nenad Corbic +# +# Copyright: (c) 2005 Anthony Minessale II +# +# 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. +################################################################################ + +SMG_DTMF=YES + +#Default kernel directory to be overwritten by user +#Kernel version and location +ifndef KVER + KVER=$(shell uname -r) +endif +ifndef KMOD + KMOD=/lib/modules/$(KVER) +endif +ifndef KDIR + KDIR=$(KMOD)/build +endif +ifndef KINSTDIR + KINSTDIR=$(KMOD)/kernel +endif + +CC = gcc +INSTALLPREFIX= + +INCLUDES = -I$(KDIR)/include -I ../../ssmg/libsangoma.trunk -I. -I ../../patches/kdrivers/include -I ../../patches/kdrivers/wanec/oct6100_api/include -I ../../patches/kdrivers/wanec -I/usr/local/include -I../../patches/kdrivers/include -I/usr/include/wanpipe -Ilib/libteletone/src + +CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 +CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g +LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm + + +ifeq "${SMG_DTMF}" "YES" +LDFLAGS+= -lteletone +CFLAGS+= -DSMG_DTMF_ENABLE +endif + + +all: sangoma_mgd + +libs: + $(shell cd lib/libteletone; ./configure --prefix=$(INSTALLPREFIX); cd ../../; ) + $(MAKE) -C lib/libteletone all + +switch_buffer.o: switch_buffer.c switch_buffer.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o switch_buffer.o switch_buffer.c + +call_signal.o: call_signal.c call_signal.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o call_signal.o call_signal.c + +sangoma_mgd: sangoma_mgd.o call_signal.o switch_buffer.o sigboost.h + rm -fr core* + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -o sangoma_mgd sangoma_mgd.o switch_buffer.o call_signal.o $(LDFLAGS) + +sangoma_mgd.o: sangoma_mgd.c sangoma_mgd.h sigboost.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o sangoma_mgd.o sangoma_mgd.c + + +clean: old_cleanup + make -C lib/libteletone clean + find . -name '*.o' | xargs rm -f + rm -fr sangoma_mgd pritest *.o *.so *~ *core* *.so* *.a + +distclean: clean + @echo OK + +install: all install_smg old_cleanup + +install_smg: old_cleanup + install -D -m 755 sangoma_mgd $(INSTALLPREFIX)/usr/sbin/sangoma_mgd + @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ + install -D -m 755 sangoma_mgd.conf.sample $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ + fi + install -D -m 755 smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl + install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/etc/init.d/smgss7_init_ctrl + install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/usr/sbin/smgss7_init_ctrl + @echo "sangoma_mgd Installed" + +old_cleanup: + ./scripts/old_cleanup.sh + + +install_all: all install_smg + +uninstall: + /bin/rm $(INSTALLPREFIX)/usr/sbin/sangoma_mgd $(INSTALLPREFIX)/etc/sangoma_mgd.conf + + + diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.4.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.4.tmp new file mode 100644 index 0000000..3599227 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.4.tmp @@ -0,0 +1,4986 @@ +/********************************************************************************* + * sangoma_mgd.c -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards + * + * Copyright 05-07, Nenad Corbic + * Anthony Minessale II + * + * This program is free software, distributed under the terms of + * the GNU General Public License + * + * ============================================= +<<<<<<< .mine + * v1.22 Nenad Corbic + * Bug fix on socket open. Check for retun code >= 0 + * +======= + * v1.22 Nenad Corbic + * Nov 27 2007 + * Updated DTMF Tx function + * Fixed - dtmf tx without voice + * Fxied - dtmf clipping. + * +>>>>>>> .r41 + * v1.21 Nenad Corbic + * Nov 25 2007 + * Major unit testing of each state + * Numerous bug fixes for non autoacm mode. + * Changed "Channel-Name" to tg/cic + * Added compile option WANPIPE_CHAN_NAME to change Asterisk channel + * name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE}) + * instead of WOOMERA (for example) + * + * v1.20 Nenad Corbic + * Added option for Auto ACM response mode. + * + * v1.19 Nenad Corbic + * Configurable DTMF + * Bug fix in release codes (all ckt busy) + * + * v1.18 Nenad Corbic + * Added new rel cause support based on + * digits instead of strings. + * + * v1.17 Nenad Corbic + * Added session support + * + * v1.16 Nenad Corbic + * Added hwec disable on loop ccr + * + * v1.15 Nenad Corbic + * Updated DTMF Locking + * Added delay between digits + * + * v1.14 Nenad Corbic + * Updated DTMF Library + * Fixed DTMF synchronization + * + * v1.13 Nenad Corbic + * Woomera OPAL Dialect + * Added Congestion control + * Added SCTP + * Added priority ISUP queue + * Fixed presentation + * + * v1.12 Nenad Corbic + * Fixed CCR + * Removed socket shutdown on end call. + * Let Media thread shutodwn sockets. + * + * v1.11 Nenad Corbic + * Fixed Remote asterisk/woomera connection + * Increased socket timeouts + * + * v1.10 Nenad Corbic + * Added Woomera OPAL dialect. + * Start montor thread in priority + * + * v1.9 Nenad Corbic + * Added Loop mode for ccr + * Added remote debug enable + * Fixed syslog logging. + * + * v1.8 Nenad Corbic + * Added a ccr loop mode for each channel. + * Boost can set any channel in loop mode + * + * v1.7 Nenad Corbic + * Pass trunk group number to incoming call + * chan woomera will use it to append to context + * name. Added presentation feature. + * + * v1.6 Nenad Corbic + * Use only ALAW and MLAW not SLIN. + * This reduces the load quite a bit. + * Send out ALAW/ULAW format on HELLO message. + * RxTx Gain is done now in chan_woomera. + * + * v1.5 Nenad Corbic + * Bug fix in START_NACK_ACK handling. + * When we receive START_NACK we must alwasy pull tank before + * we send out NACK_ACK this way we will not try to send NACK + * ourself. + *********************************************************************************/ + +#include "sangoma_mgd.h" +#include "q931_cause.h" + + +#define USE_SYSLOG 1 +#define CODEC_LAW_DEFAULT 1 + +#ifdef CODEC_LAW_DEFAULT +static uint32_t codec_sample=8; +#else +static uint32_t codec_sample=16; +#endif + +static char ps_progname[]="sangoma_mgd"; + +static struct woomera_interface woomera_dead_dev; + +#if 0 +#define DOTRACE +#endif + + +#define SMG_VERSION "v1.22" + +/* enable early media */ +#if 1 +#define WOOMERA_EARLY_MEDIA 1 +#endif + + +#define SMG_DTMF_ON 60 +#define SMG_DTMF_OFF 10 +#define SMG_DTMF_RATE 8000 + +#if 0 +#define MEDIA_SOCK_SHUTDOWN 1 +#endif + +#ifdef DOTRACE +static int tc = 0; +#endif + +#if 0 +#warning "NENAD: HPTDM API" +#define WP_HPTDM_API 1 +#else +#undef WP_HPTDM_API +#endif + +#ifdef WP_HPTDM_API +hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; +#endif + +#undef SMG_CALLING_NAME + +const char WELCOME_TEXT[] = +"================================================================================\n" +"Sangoma Media Gateway Daemon v1.22 \n" +"TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n" +"Copyright 2005, 2006, 2007 \n" +"Nenad Corbic , Anthony Minessale II \n" +"This program is free software, distributed under the terms of\n" +"the GNU General Public License\n" +"================================================================================\n" +""; + + +static int master_reset=0; + +static int coredump=1; +static int autoacm=1; + +static int launch_media_tdm_thread(struct woomera_interface *woomera); +static int launch_woomera_thread(struct woomera_interface *woomera); +static struct woomera_interface *alloc_woomera(void); + +q931_cause_to_str_array_t q931_cause_to_str_array[255]; + + +#if 0 +static uint32_t string_to_release(char *code) +{ + if (code) { + if (!strcasecmp(code, "CHANUNAVAIL")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "INVALID")) { + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "ERROR")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + if (!strcasecmp(code, "CONGESTION")) { + //return SIGBOOST_RELEASE_CAUSE_BUSY; + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "BUSY")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "NOANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "ANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NORMAL; + } + + if (!strcasecmp(code, "CANCEL")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "UNKNOWN")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + } + return SIGBOOST_RELEASE_CAUSE_NORMAL; +} + +static char * release_to_string(uint32_t rel_cause) +{ + switch (rel_cause) { + + case SIGBOOST_RELEASE_CAUSE_UNDEFINED: + return "UNKNOWN"; + case SIGBOOST_RELEASE_CAUSE_NORMAL: + return "NORMAL"; + case SIGBOOST_RELEASE_CAUSE_BUSY: + return "BUSY"; + case SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST: + return "CHANUNAVAIL"; + case SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET: + return "CANCEL"; + case SIGBOOST_RELEASE_CAUSE_NOANSWER: + return "NOANSWER"; + case SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT: + return "TIMEOUT"; + case SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY: + return "CONGESTION"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_SMALL: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_SMALL: + return "ERROR"; + } + + return "NORMAL"; +} +#endif + + + +void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return; + } + + if (level && level > server.debug) { + return; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + } else { + char date[80] = ""; + struct tm now; + time_t epoch; + + if (time(&epoch) && localtime_r(&epoch, &now)) { + strftime(date, sizeof(date), "%Y-%m-%d %T", &now); + } + +#ifdef USE_SYSLOG + syslog(LOG_DEBUG | LOG_LOCAL2, data); +#else + fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data); +#endif + free(data); + } +#ifndef USE_SYSLOG + fflush(fp); +#endif +} + + + + +static int isup_exec_command(int span, int chan, int id, int cmd, int cause) +{ + call_signal_event_t oevent; + int retry=5; + + call_signal_event_init(&oevent, cmd, chan, span); + oevent.release_cause = cause; + + if (id >= 0) { + oevent.call_setup_id = id; + } +isup_exec_cmd_retry: + if (call_signal_connection_write(&server.mcon, &oevent) <= 0){ + + --retry; + if (retry <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket: %s\n", + strerror(errno)); + return -1; + } else { + log_printf(0, server.log, + "System Warning: Failed to tx on ISUP socket: %s :retry %i\n", + strerror(errno),retry); + } + + goto isup_exec_cmd_retry; + } + + return 0; +} + +static int socket_printf(int socket, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return -1; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + log_printf(0, server.log, "Crtical ERROR: Memory Error!\n"); + } else { + int err; + int len = strlen(data); + err=send(socket, data, strlen(data), 0); + if (err != strlen(data)) { + log_printf(2, server.log, "ERROR: Failed to send data to woomera socket(%i): err=%i len=%d %s\n", + socket,err,len,strerror(errno)); + ret = err; + } else { + ret = 0; + } + + free(data); + } + + return ret; +} + + + +static int woomera_next_pair(struct woomera_config *cfg, char **var, char **val) +{ + int ret = 0; + char *p, *end; + + *var = *val = NULL; + + for(;;) { + cfg->lineno++; + + if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) { + ret = 0; + break; + } + + *var = cfg->buf; + + if (**var == '[' && (end = strchr(*var, ']'))) { + *end = '\0'; + (*var)++; + strncpy(cfg->category, *var, sizeof(cfg->category) - 1); + continue; + } + + if (**var == '#' || **var == '\n' || **var == '\r') { + continue; + } + + if ((end = strchr(*var, '#'))) { + *end = '\0'; + end--; + } else if ((end = strchr(*var, '\n'))) { + if (*end - 1 == '\r') { + end--; + } + *end = '\0'; + } + + p = *var; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *var = p; + + if (!(*val = strchr(*var, '='))) { + ret = -1; + log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); + continue; + } else { + p = *val - 1; + *(*val) = '\0'; + (*val)++; + if (*(*val) == '>') { + *(*val) = '\0'; + (*val)++; + } + + while ((*p == ' ' || *p == '\t') && p != *var) { + *p = '\0'; + p--; + } + + p = *val; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *val = p; + ret = 1; + break; + } + } + + return ret; + +} + + +#if 0 +static void woomera_set_span_chan(struct woomera_interface *woomera, int span, int chan) +{ + pthread_mutex_lock(&woomera->vlock); + woomera->span = span; + woomera->chan = chan; + pthread_mutex_unlock(&woomera->vlock); + +} +#endif + + +static struct woomera_event *new_woomera_event_printf(struct woomera_event *ebuf, char *fmt, ...) +{ + struct woomera_event *event = NULL; + int ret = 0; + va_list ap; + + if (ebuf) { + event = ebuf; + } else if (!(event = new_woomera_event())) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + return NULL; + } else { + return NULL; + } + + va_start(ap, fmt); +#ifdef SOLARIS + event->data = (char *) malloc(2048); + vsnprintf(event->data, 2048, fmt, ap); +#else + ret = vasprintf(&event->data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + destroy_woomera_event(&event, EVENT_FREE_DATA); + return NULL; + } + + return event; + +} + +static struct woomera_event *woomera_clone_event(struct woomera_event *event) +{ + struct woomera_event *clone; + + if (!(clone = new_woomera_event())) { + return NULL; + } + + memcpy(clone, event, sizeof(*event)); + clone->next = NULL; + clone->data = strdup(event->data); + + return clone; +} + +static void enqueue_event(struct woomera_interface *woomera, + struct woomera_event *event, + event_args free_data) +{ + struct woomera_event *ptr, *clone = NULL; + + assert(woomera != NULL); + assert(event != NULL); + + if (!(clone = woomera_clone_event(event))) { + log_printf(0, server.log, "Error Cloning Event\n"); + return; + } + + pthread_mutex_lock(&woomera->queue_lock); + + for (ptr = woomera->event_queue; ptr && ptr->next ; ptr = ptr->next); + + if (ptr) { + ptr->next = clone; + } else { + woomera->event_queue = clone; + } + + pthread_mutex_unlock(&woomera->queue_lock); + + woomera_set_flag(woomera, WFLAG_EVENT); + + if (free_data && event->data) { + /* The event has been duplicated, the original data + * should be freed */ + free(event->data); + event->data=NULL; + } +} + +static char *dequeue_event(struct woomera_interface *woomera) +{ + struct woomera_event *event; + char *data = NULL; + + if (!woomera) { + return NULL; + } + + pthread_mutex_lock(&woomera->queue_lock); + if (woomera->event_queue) { + event = woomera->event_queue; + woomera->event_queue = event->next; + data = event->data; + pthread_mutex_unlock(&woomera->queue_lock); + + destroy_woomera_event(&event, EVENT_KEEP_DATA); + return data; + } + pthread_mutex_unlock(&woomera->queue_lock); + + return data; +} + + +static int enqueue_event_on_listeners(struct woomera_event *event) +{ + struct woomera_listener *ptr; + int x = 0; + + assert(event != NULL); + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + enqueue_event(ptr->woomera, event, EVENT_KEEP_DATA); + x++; + } + pthread_mutex_unlock(&server.listen_lock); + + return x; +} + + +static void del_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *ptr, *last = NULL; + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + if (ptr->woomera == woomera) { + if (last) { + last->next = ptr->next; + } else { + server.listeners = ptr->next; + } + free(ptr); + break; + } + last = ptr; + } + pthread_mutex_unlock(&server.listen_lock); +} + +static void add_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *new; + + pthread_mutex_lock(&server.listen_lock); + + if ((new = malloc(sizeof(*new)))) { + memset(new, 0, sizeof(*new)); + new->woomera = woomera; + new->next = server.listeners; + server.listeners = new; + } else { + log_printf(0, server.log, "Memory Error adding listener!\n"); + } + + pthread_mutex_unlock(&server.listen_lock); +} + + + +static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) +{ + struct media_session *ms = woomera_get_ms(woomera); + char *cur = NULL; + int wrote = 0; + int err; + + if (!ms) { + return -EINVAL; + } + + if (!ms->dtmf_buffer) { + log_printf(3, woomera->log, "Allocate DTMF Buffer...."); + + err=switch_buffer_create_dynamic(&ms->dtmf_buffer, 1024, server.dtmf_size, 0); + + if (err != 0) { + log_printf(0, woomera->log, "Failed to allocate DTMF Buffer!\n"); + return -ENOMEM; + } else { + log_printf(3, woomera->log, "SUCCESS!\n"); + } + + } + + log_printf(3, woomera->log, "Sending DTMF %s\n",digits); + for (cur = digits; *cur; cur++) { + if ((wrote = teletone_mux_tones(&ms->tone_session, + &ms->tone_session.TONES[(int)*cur]))) { + + pthread_mutex_lock(&woomera->dtmf_lock); + + err=switch_buffer_write(ms->dtmf_buffer, ms->tone_session.buffer, wrote * 2); + + pthread_mutex_unlock(&woomera->dtmf_lock); + + log_printf(3, woomera->log, "Sending DTMF %s Wrote=%i (err=%i)\n", + digits,wrote*2,err); + } else { + log_printf(0, woomera->log, "Error: Sending DTMF %s (err=%i)\n", + digits,wrote); + } + } + + ms->skip_read_frames = 200; + return 0; +} + +static struct woomera_interface *alloc_woomera(void) +{ + struct woomera_interface *woomera = NULL; + + if ((woomera = malloc(sizeof(struct woomera_interface)))) { + + memset(woomera, 0, sizeof(struct woomera_interface)); + + woomera->chan = -1; + woomera->span = -1; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->q931_rel_cause_topbx=SIGBOOST_RELEASE_CAUSE_NORMAL; + woomera->q931_rel_cause_tosig=SIGBOOST_RELEASE_CAUSE_NORMAL; + + woomera_set_interface(woomera, "w-1g-1"); + + + + } + + return woomera; + +} + + +static struct woomera_interface *new_woomera_interface(int socket, struct sockaddr_in *sock_addr, int len) +{ + struct woomera_interface *woomera = NULL; + + if (socket < 0) { + log_printf(0, server.log, "Critical: Invalid Socket on new interface!\n"); + return NULL; + } + + if ((woomera = alloc_woomera())) { + if (socket >= 0) { + no_nagle(socket); + woomera->socket = socket; + } + + if (sock_addr && len) { + memcpy(&woomera->addr, sock_addr, len); + } + } + + return woomera; + +} + +static char *woomera_message_header(struct woomera_message *wmsg, char *key) +{ + int x = 0; + char *value = NULL; + + for (x = 0 ; x < wmsg->last ; x++) { + if (!strcasecmp(wmsg->names[x], key)) { + value = wmsg->values[x]; + break; + } + } + + return value; +} + + +#if 1 + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + + +static int waitfor_tx_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if (pfds[0].revents & POLLOUT) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + + +#else + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags | errflags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & errflags)) { + res = -1; + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X)!\n", + pfds[0].revents); +#endif + res = -1; + } + } + + return res; +} + +#endif + +#if 1 +static int waitfor_2sockets(int fda, int fdb, char *a, char *b, int timeout) +{ + struct pollfd pfds[2]; + int res = 0; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + if (fda < 0 || fdb < 0) { + return -1; + } + + *a=0; + *b=0; + + memset(pfds, 0, sizeof(pfds)); + pfds[0].fd = fda; + pfds[1].fd = fdb; + pfds[0].events = POLLIN | errflags; + pfds[1].events = POLLIN | errflags; + if ((res = poll(pfds, 2, timeout)) > 0) { + res = 1; + if ((pfds[0].revents & errflags) || (pfds[1].revents & errflags)) { + res = -1; + } else { + if ((pfds[0].revents & POLLIN)) { + *a=1; + res++; + } + if ((pfds[1].revents & POLLIN)) { + *b=1; + res++; + } + } + + if (res == 1) { + /* No event found what to do */ + res=-1; + } + } + + return res; +} +#endif + + +static struct media_session *media_session_new(struct woomera_interface *woomera) +{ + struct media_session *ms = NULL; + int x; + char *p; + int span,chan; + + span=woomera->span; + chan=woomera->chan; + + log_printf(2, server.log,"Starting new MEDIA session [%s] [%s]\n", + woomera->interface,woomera->raw?woomera->raw:"N/A"); + + if ((ms = malloc(sizeof(struct media_session)))) { + memset(ms, 0, sizeof(struct media_session)); + + if (woomera->loop_tdm != 1) { + for(x = 0; x < strlen(woomera->raw) ; x++) { + if (woomera->raw[x] == ':') { + break; + } + if (woomera->raw[x] == '/') { + break; + } + } + + ms->ip = strndup(woomera->raw, x); + time(&ms->started); + p = woomera->raw + (x+1); + ms->port = atoi(p); + } + + time(&ms->started); + woomera_set_ms(woomera,ms); + ms->woomera = woomera; + + /* Setup artificial DTMF stuff */ + memset(&ms->tone_session, 0, sizeof(ms->tone_session)); + if (teletone_init_session(&ms->tone_session, 0, NULL, NULL)) { + log_printf(0, server.log, "ERROR: Failed to initialize TONE [w%ig%i]!\n", + span+1,chan+1); + } + + ms->tone_session.rate = SMG_DTMF_RATE; + ms->tone_session.duration = server.dtmf_on * (ms->tone_session.rate / 1000); + ms->tone_session.wait = server.dtmf_off * (ms->tone_session.rate / 1000); + + teletone_dtmf_detect_init (&ms->dtmf_detect, SMG_DTMF_RATE); + + } else { + log_printf(0, server.log, "ERROR: Memory Alloc Failed [w%ig%i]!\n", + span+1,chan+1); + } + + return ms; +} + +static void media_session_free(struct media_session *ms) +{ + if (ms->ip) { + free(ms->ip); + } + + teletone_destroy_session(&ms->tone_session); + switch_buffer_destroy(&ms->dtmf_buffer); + + ms->woomera = NULL; + + free(ms); +} + + +static int create_udp_socket(struct media_session *ms, char *local_ip, int local_port, char *ip, int port) +{ + int rc; + struct hostent *result, *local_result; + char buf[512], local_buf[512]; + int err = 0; + + log_printf(5,server.log,"LocalIP %s:%d IP %s:%d \n",local_ip, local_port, ip, port); + + memset(&ms->remote_hp, 0, sizeof(ms->remote_hp)); + memset(&ms->local_hp, 0, sizeof(ms->local_hp)); + if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { + gethostbyname_r(ip, &ms->remote_hp, buf, sizeof(buf), &result, &err); + gethostbyname_r(local_ip, &ms->local_hp, local_buf, sizeof(local_buf), &local_result, &err); + if (result && local_result) { + ms->remote_addr.sin_family = ms->remote_hp.h_addrtype; + memcpy((char *) &ms->remote_addr.sin_addr.s_addr, ms->remote_hp.h_addr_list[0], ms->remote_hp.h_length); + ms->remote_addr.sin_port = htons(port); + + ms->local_addr.sin_family = ms->local_hp.h_addrtype; + memcpy((char *) &ms->local_addr.sin_addr.s_addr, ms->local_hp.h_addr_list[0], ms->local_hp.h_length); + ms->local_addr.sin_port = htons(local_port); + + rc = bind(ms->socket, (struct sockaddr *) &ms->local_addr, sizeof(ms->local_addr)); + if (rc < 0) { + close(ms->socket); + ms->socket = -1; + + log_printf(5,server.log, + "Failed to bind LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + + /* OK */ + + } else { + log_printf(0,server.log, + "Failed to get hostbyname LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + } else { + log_printf(0,server.log, + "Failed to create/allocate UDP socket\n"); + } + + return ms->socket; +} + +static int next_media_port(void) +{ + int port; + + pthread_mutex_lock(&server.media_udp_port_lock); + port = ++server.next_media_port; + if (port > WOOMERA_MAX_MEDIA_PORT) { + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + port = WOOMERA_MIN_MEDIA_PORT; + } + pthread_mutex_unlock(&server.media_udp_port_lock); + + return port; +} + + + +static int woomera_dtmf_transmit(struct media_session *ms, int mtu) +{ + struct woomera_interface *woomera = ms->woomera; + int bread; + unsigned char dtmf[1024]; + unsigned char dtmf_law[1024]; + sangoma_api_hdr_t hdrframe; + int i; + int slin_len = mtu*2; + short *data; + int used; + int res; + int err; + int txdtmf=0; + memset(&hdrframe,0,sizeof(hdrframe)); + + if (!ms->dtmf_buffer) { + return -1; + } + + for (;;) { + + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + break; + } + + res = waitfor_tx_socket(ms->sangoma_sock, -1, POLLERR | POLLOUT); + if (res <= 0) { + break; + } + +#ifdef CODEC_LAW_DEFAULT + + pthread_mutex_lock(&woomera->dtmf_lock); + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + pthread_mutex_unlock(&woomera->dtmf_lock); + break; + } + + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, slin_len); + pthread_mutex_unlock(&woomera->dtmf_lock); + + if (bread <= 0) { + break; + } + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes MTU=%i Coding=%i Used=%i\n", + woomera->interface,bread,mtu,ms->hw_coding,used); + + data=(short*)dtmf; + for (i=0;ihw_coding) { + /* ALAW */ + dtmf_law[i] = linear_to_alaw((int)data[i]); + } else { + /* ULAW */ + dtmf_law[i] = linear_to_ulaw((int)data[i]); + } + } + + err=sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf_law, mtu, 0); + + if (err != mtu) { + log_printf(0, woomera->log, "Error: Failed to TX to TDM API on DTMF (err=%i mtu=%i)!\n",err,mtu); + } + + txdtmf++; + ms->skip_write_frames++; +#else +... + pthread_mutex_lock(&woomera->dtmf_lock); + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, mtu); + pthread_mutex_unlock(&woomera->dtmf_lock); + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes\n", + woomera->interface,bread); + + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf, mtu, 0); + txdtmf++; + ms->skip_write_frames++; +#endif + + } + + if (txdtmf) { + return 0; + } else { + return -1; + } +} + +static void media_loop_run(struct media_session *ms) +{ + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int errs=0; + int res=0; + wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + char filename[100]; + FILE *filed=NULL; + int loops=0; + + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + + log_printf(1, server.log, "Media Loop Started %s fd=%i\n", + woomera->interface,ms->sangoma_sock); + + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "WANPIPE MEDIA Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + + + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } + + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + sangoma_tdm_disable_hwec(ms->sangoma_sock,&tdm_api); + + } + + if (errs) { + + log_printf(0, server.log, "Media Loop: failed to open tdm device %s\n", + woomera->interface); + return; + } + + if (server.loop_trace) { + sprintf(filename,"/smg/w%ig%i-loop.trace",woomera->span+1,woomera->chan+1); + unlink(filename); + filed = safe_fopen(filename, "w"); + } + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + ((res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2)) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + log_printf(0, server.log, "Media Loop Restart %s\n", + woomera->interface); + continue; + } + + if (res < 0 ){ + log_printf(0, server.log, "Media Loop Socket error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM Loop ReadMsg Error: %s\n", + strerror(errno), woomera->interface); + break; + } + + if (server.loop_trace && filed != NULL) { + int i; + for (i=0;isangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + res, 0); + + res=0; + + loops++; + } + + + if (res < 0) { + log_printf(2, server.log, "Media Loop: socket error %s (fd=%i)!\n", + woomera->interface, ms->sangoma_sock); + } + + + if (server.loop_trace && filed != NULL) { + fclose(filed); + } + + sangoma_tdm_enable_hwec(ms->sangoma_sock,&tdm_api); + + sleep(1); + + close_socket(&ms->sangoma_sock); + + log_printf(1, server.log, "Media Loop Finished %s Master=%i MediaEnd=%i Loops=%i\n", + woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_MEDIA_END),loops); + + return; + +} + +#ifdef WP_HPTDM_API +static int media_rx_ready(void *p, unsigned char *data, int len) +{ + struct media_session *ms = (struct media_session *)p; + + if (ms->udp_sock < 0) { + return -1; + } + + return sendto(ms->udp_sock, + data,len, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + +} +#endif + +static void *media_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int local_port, x = 0, errs = 0, res = 0, packet_len = 0; + //int udp_cnt=0; + struct woomera_event wevent; + wanpipe_tdm_api_t tdm_api; + FILE *tx_fd=NULL; + int sock_timeout=200; + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + !woomera->interface || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(2, server.log, + "MEDIA session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(ms); + pthread_exit(NULL); + return NULL; + } + + + log_printf(2, server.log, "MEDIA session for [%s] started (ptr=%p loop=%i)\n", + woomera->interface,woomera,woomera->loop_tdm); + + if (woomera->loop_tdm) { + media_loop_run(ms); + ms->udp_sock=-1; + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + goto media_thread_exit; + } + + for(x = 0; x < 1000 ; x++) { + local_port = next_media_port(); + if ((ms->udp_sock = create_udp_socket(ms, server.media_ip, local_port, ms->ip, ms->port)) > -1) { + break; + } + } + + if (ms->udp_sock < 0) { + log_printf(0, server.log, "UDP Socket Error (%s) [%s] LocalPort=%d\n", + strerror(errno), woomera->interface, local_port); + + errs++; + } else { + +#ifdef WP_HPTDM_API + hp_tdm_api_span_t *span=hptdmspan[woomera->span+1]; + if (!span || !span->init) { + errs++; + } else { + hp_tdm_api_usr_callback_t usr_callback; + memset(&usr_callback,0,sizeof(usr_callback)); + usr_callback.p = ms; + usr_callback.rx_avail = media_rx_ready; + if (span->open_chan(span, &usr_callback, &ms->tdmchan,woomera->chan+1)) { + errs++; + } + } +#else + if ((ms->sangoma_sock = sangoma_create_socket_by_name(woomera->interface, NULL)) < 0) { + log_printf(0, server.log, "WANPIPE Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + +# ifdef CODEC_LAW_DEFAULT + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } +# else + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_SLINEAR) < 0 ) { + errs++; + } +# endif + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + +# ifdef CODEC_LAW_DEFAULT +# ifdef LIBSANGOMA_GET_HWCODING + ms->hw_coding=sangoma_tdm_get_hw_coding(ms->sangoma_sock, &tdm_api); + if (ms->hw_coding < 0) { + errs++; + } +# else +# error "libsangoma missing hwcoding feature: not up to date!" +# endif +# endif + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + } +#endif + } + + + +#ifdef WP_HPTDM_API + /* No tdm thread */ +#else + if (!errs && + launch_media_tdm_thread(woomera)) { + errs++; + } +#endif + + if (!errs) { + + unsigned char udp_frame[4096]; + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(udp_frame,0,sizeof(udp_frame)); +#ifdef DOTRACE + int fdin, fdout; + char path_in[512], path_out[512]; +#endif + + + +#if 0 + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: %s%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + ms->hw_coding ?"ALAW":"ULAW", + WOOMERA_RECORD_SEPERATOR + ); +#else + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Unique-Call-Id: %s%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: PCM-16%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + WOOMERA_RECORD_SEPERATOR + ); +#endif + + + enqueue_event(woomera, &wevent, EVENT_FREE_DATA); + +#ifdef DOTRACE + sprintf(path_in, "/tmp/debug-in.%d.raw", tc); + sprintf(path_out, "/tmp/debug-out.%d.raw", tc++); + fdin = open(path_in, O_WRONLY | O_CREAT, O_TRUNC, 0600); + fdout = open(path_out, O_WRONLY | O_CREAT, O_TRUNC, 0600); +#endif + + if (server.out_tx_test) { + tx_fd=fopen("/smg/sound.raw","rb"); + if (!tx_fd){ + log_printf(0,server.log, "FAILED TO OPEN Sound file!\n"); + } + } + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + (res = waitfor_socket(ms->udp_sock, sock_timeout, POLLERR | POLLIN)) >= 0) { + + unsigned int fromlen = sizeof(struct sockaddr_in); + + + if (res == 0) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + + log_printf(4, server.log, "%s: UDP Sock Timeout !!!\n", + woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if ((packet_len = recvfrom(ms->udp_sock, udp_frame, sizeof(udp_frame), + MSG_DONTWAIT, (struct sockaddr *) &ms->local_addr, &fromlen)) < 1) { + log_printf(2, server.log, "UDP Recv Error: %s\n",strerror(errno)); + break; + } + +#if 0 + log_printf(6, server.log, "%s: UDP Receive %i !!!\n", + woomera->interface,packet_len); +#endif + + if (packet_len > 0) { + + if (packet_len != sangoma_frame_len && ms->udp_sync_cnt <= 5) { + /* Assume that we will always receive SLINEAR here */ + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, packet_len/codec_sample); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + log_printf(0, server.log, + "%s: UDP TDM Period ReSync to Len=%i %ims (udp=%i) \n", + woomera->interface,sangoma_frame_len, + sangoma_frame_len/codec_sample,packet_len); + + + if (++ms->udp_sync_cnt >= 6) { + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, 20); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + log_printf(0, server.log, + "%s: UDP TDM Period Force ReSync to 20ms \n", + woomera->interface); + } + + } + + if (!server.out_tx_test) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + /* For sanity sake if we are doing the out test + * dont take any chances force tx udp data */ + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + continue; + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + continue; + } + + } + + if (server.out_tx_test && tx_fd && + fread((void*)udp_frame, + sizeof(char), + packet_len,tx_fd) <= 0) { + + sangoma_get_full_cfg(ms->sangoma_sock,&tdm_api); + fclose(tx_fd); + tx_fd=NULL; + } + +#ifdef WP_HPTDM_API + if (ms->tdmchan->push) { + ms->tdmchan->push(ms->tdmchan,udp_frame,packet_len); + } +#else + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + udp_frame, + packet_len, 0); +#endif + + } + +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + udp_cnt++; + if (udp_cnt && udp_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA UDP TX RX CNT %i %i\n", + woomera->interface,udp_cnt,packet_len); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media Thread: socket error !\n"); + } + } + + + + new_woomera_event_printf(&wevent, + "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Start-Time: %ld%s" + "End-Time: %ld%s" + "Answer-Time: %ld%s" + "Call-ID: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + woomera->session, + WOOMERA_LINE_SEPERATOR, + + time(&ms->started), + WOOMERA_LINE_SEPERATOR, + + time(NULL), + WOOMERA_LINE_SEPERATOR, + + time(&ms->answered), + WOOMERA_LINE_SEPERATOR, + + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + +media_thread_exit: + + if (woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + usleep(1000); + sched_yield(); + } + } + + + close_socket(&ms->udp_sock); + close_socket(&ms->sangoma_sock); + + if (tx_fd){ + fclose(tx_fd); + tx_fd=NULL; + } + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + + woomera_set_ms(woomera,NULL); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + + media_session_free(ms); + + log_printf(2, server.log, "MEDIA session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + + pthread_exit(NULL); + return NULL; +} + + + + +static void *media_tdm_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int res = 0; + //int tdm_cnt=0; + //wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + sangoma_api_hdr_t hdrframe; + + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || !woomera->interface) { + log_printf(2, server.log, "MEDIA TDM session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + pthread_exit(NULL); + return NULL; + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] started (ptr=%p)\n", + woomera->interface,woomera); + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + (res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } else if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "Media TDM Restart Failed%s\n", + woomera->interface); + break; + } + log_printf(0, server.log, "Media TDM Restart %s\n", + woomera->interface); + continue; + } else if (res < 0) { + log_printf(0, server.log, "Media TDM Sangoma Socket Error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM ReadMsg Error: %s\n", strerror(errno)); + break; + } + + res = sendto(ms->udp_sock, + circuit_frame, + res, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + if (res < 0) { + log_printf(2, server.log, "UDP Sento Error: %s\n", strerror(errno)); + break; + } +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + tdm_cnt++; + if (tdm_cnt && tdm_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA TDM TX RX CNT %i %i\n", + woomera->interface,tdm_cnt,res); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media TDM Thread: socket error !\n"); + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + + pthread_exit(NULL); + return NULL; + +} + + +/* This function must be called with process_lock + * because it modifies shared process_table */ + +static int launch_media_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms; + + if ((ms = media_session_new(woomera))) { + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_RUNNING); + result = pthread_create(&ms->thread, &attr, media_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(woomera->ms); + + } + pthread_attr_destroy(&attr); + + } else { + log_printf(0, server.log, "Failed to start new media session\n"); + } + + return result; + +} + +static int launch_media_tdm_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms = woomera_get_ms(woomera); + + if (!ms) { + return result; + } + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + result = pthread_create(&ms->thread, &attr, media_tdm_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +static struct woomera_interface * launch_woomera_loop_thread(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + char callid[20]; + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + + if ((woomera = alloc_woomera())) { + + woomera->chan = event->chan; + woomera->span = event->span; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->loop_tdm=1; + + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + woomera_set_interface(woomera,callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = woomera; + pthread_mutex_unlock(&server.process_lock); + + if (launch_woomera_thread(woomera)) { + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + free(woomera); + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + return woomera; +} + +static int woomera_message_parse(struct woomera_interface *woomera, struct woomera_message *wmsg, int timeout) +{ + char *cur, *cr, *next = NULL, *eor = NULL; + char buf[2048]; + int res = 0, bytes = 0, sanity = 0; + struct timeval started, ended; + int elapsed, loops = 0; + int failto = 0; + int packet = 0; + + memset(wmsg, 0, sizeof(*wmsg)); + + if (woomera->socket < 0 ) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Invalid Socket! %d\n", + woomera->interface,woomera->socket); + return -1; + } + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP !\n", + woomera->interface); + return -1; + } + + gettimeofday(&started, NULL); + memset(buf, 0, sizeof(buf)); + + if (timeout < 0) { + timeout = abs(timeout); + failto = 1; + } else if (timeout == 0) { + timeout = -1; + } + + + while (!(eor = strstr(buf, WOOMERA_RECORD_SEPERATOR))) { + if (sanity > 1000) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Failed Sanity Check!\n[%s]\n\n", woomera->interface, buf); + return -1; + } + + if ((res = waitfor_socket(woomera->socket, 1000, POLLERR | POLLIN) > 0)) { + res = recv(woomera->socket, buf, sizeof(buf), MSG_PEEK); + + if (res > 1) { + packet++; + } + if (!strncmp(buf, WOOMERA_LINE_SEPERATOR, 2)) { + res = read(woomera->socket, buf, 2); + return 0; + } + if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + } else if (res < 0) { + log_printf(3, woomera->log, WOOMERA_DEBUG_PREFIX + "%s error during packet retry #%d\n", + woomera->interface, loops); + return res; + } else if (loops) { + ysleep(100000); + } + } + + gettimeofday(&ended, NULL); + elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000)); + + if (res < 0) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Bad RECV\n", + woomera->interface); + return res; + } else if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + } + + if (packet && loops > 150) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout waiting for packet.\n", + woomera->interface); + return -1; + } + + if (timeout > 0 && (elapsed > timeout)) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout [%d] reached\n", + woomera->interface, timeout); + return failto ? -1 : 0; + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)) { + /* BRB! we have an Event to deliver....*/ + return 0; + } + + /* what're we still doing here? */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + !woomera_test_flag(woomera, WFLAG_RUNNING)) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MASTER RUNNING or RUNNING!\n", woomera->interface); + return -1; + } + loops++; + } + + *eor = '\0'; + bytes = strlen(buf) + 4; + + memset(buf, 0, sizeof(buf)); + res = read(woomera->socket, buf, bytes); + next = buf; + + if (woomera->debug > 1) { + log_printf(3, woomera->log, "%s:WOOMERA RX MSG: %s\n",woomera->interface,buf); + + } + + while ((cur = next)) { + + if ((cr = strstr(cur, WOOMERA_LINE_SEPERATOR))) { + *cr = '\0'; + next = cr + (sizeof(WOOMERA_LINE_SEPERATOR) - 1); + if (!strcmp(next, WOOMERA_RECORD_SEPERATOR)) { + break; + } + } + if (!cur || !*cur) { + break; + } + + if (!wmsg->last) { + char *cmd, *id, *args; + woomera_set_flag(wmsg, MFLAG_EXISTS); + cmd = cur; + + if ((id = strchr(cmd, ' '))) { + *id = '\0'; + id++; + if ((args = strchr(id, ' '))) { + *args = '\0'; + args++; + strncpy(wmsg->command_args, args, sizeof(wmsg->command_args)-1); + } + strncpy(wmsg->callid, id, sizeof(wmsg->callid)-1); + } + + strncpy(wmsg->command, cmd, sizeof(wmsg->command)-1); + } else { + char *name, *val; + name = cur; + + if ((val = strchr(name, ':'))) { + *val = '\0'; + val++; + while (*val == ' ') { + *val = '\0'; + val++; + } + strncpy(wmsg->values[wmsg->last-1], val, WOOMERA_STRLEN); + } + strncpy(wmsg->names[wmsg->last-1], name, WOOMERA_STRLEN); + if (name && val && !strcasecmp(name, "content-type")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + if (name && val && !strcasecmp(name, "content-length")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + + + } + wmsg->last++; + } + + wmsg->last--; + + if (bytes && woomera_test_flag(wmsg, MFLAG_CONTENT)) { + read(woomera->socket, wmsg->body, + (bytes > sizeof(wmsg->body)) ? sizeof(wmsg->body) : bytes); + } + + return woomera_test_flag(wmsg, MFLAG_EXISTS); + +} + +static struct woomera_interface *pull_from_holding_tank(int index, int span , int chan) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + + /* Block this index until the call is completed */ + server.holding_tank[index] = &woomera_dead_dev; + + woomera->timeout = 0; + woomera->index = 0; + woomera->span=span; + woomera->chan=chan; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static void clear_from_holding_tank(int index, struct woomera_interface *woomera) +{ + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] == &woomera_dead_dev) { + server.holding_tank[index] = NULL; + } else if (woomera && server.holding_tank[index] == woomera) { + server.holding_tank[index] = NULL; + } else if (server.holding_tank[index]) { + log_printf(0, server.log, "Error: Holding tank index %i not cleared %p !\n", + index, server.holding_tank[index]); + } + pthread_mutex_unlock(&server.ht_lock); + + return; +} + +static struct woomera_interface *peek_from_holding_tank(int index) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static int add_to_holding_tank(struct woomera_interface *woomera) +{ + int next, i, found=0; + + pthread_mutex_lock(&server.ht_lock); + + for (i=0;i= CORE_TANK_LEN) { + next = server.holding_tank_index = 1; + } + + if (next == 0) { + log_printf(0, server.log, "\nCritical Error on TANK INDEX == 0\n"); + continue; + } + + if (server.holding_tank[next]) { + continue; + } + + found=1; + break; + } + + if (!found) { + /* This means all tank vales are busy + * should never happend */ + pthread_mutex_unlock(&server.ht_lock); + log_printf(0, server.log, "\nCritical Error failed to obtain a TANK INDEX\n"); + return 0; + } + + server.holding_tank[next] = woomera; + woomera->timeout = time(NULL) + 100; + + pthread_mutex_unlock(&server.ht_lock); + return next; +} + +static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, + struct woomera_message *wmsg, + int media, int answer, int accept) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + + log_printf(4, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + + if (woomera_test_flag(woomera, WFLAG_HANGUP) || + !woomera_test_flag(woomera, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END)) { + + log_printf(2, server.log, + "ERROR! call was cancelled MEDIA on HANGUP or MEDIA END!\n"); + + woomera->timeout=0; + return -1; + } + + log_printf(3, server.log,"WOOMERA: GOT %s EVENT: [%s] RAW=%s\n", + wmsg->command,wmsg->callid,raw); + + + if (raw && + woomera->raw == NULL && + !woomera_test_flag(woomera, WFLAG_RAW_MEDIA_STARTED)) { + + woomera_set_flag(woomera, WFLAG_RAW_MEDIA_STARTED); + + woomera_set_raw(woomera, raw); + + if (launch_media_thread(woomera)) { + struct woomera_event wevent; + + log_printf(4, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + woomera->timeout=0; + return -1; + } + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + + } else { + + if (accept) { + if (!autoacm) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + } + + if (answer) { + struct media_session *ms; + + pthread_mutex_lock(&woomera->ms_lock); + if ((ms=woomera->ms)) { + time(&woomera->ms->answered); + } + pthread_mutex_unlock(&woomera->ms_lock); + + if (ms) { + + if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_ANSWERED, + 0); + log_printf(2, server.log, + "Sent SIGBOOST_EVENT_CALL_ANSWERED [w%dg%d]\n", + woomera->span+1,woomera->chan+1); + } else { + struct woomera_event wevent; + log_printf(0, server.log, + "WOOMERA ANSWER: FAILED [%s] no Media \n", + wmsg->command,wmsg->callid); + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + woomera->timeout=0; + return -1; + } + } + } + + { + struct woomera_event wevent; + new_woomera_event_printf(&wevent, "200 %s OK%s" + "Unique-Call-Id: %s%s", + answer ? "ANSWER" : + accept ? "ACCEPT" : "MEDIA", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + + return 0; +} + +static int handle_woomera_call_start (struct woomera_interface *woomera, + struct woomera_message *wmsg) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + call_signal_event_t event; + char *calling = woomera_message_header(wmsg, "local-number"); +#ifdef SMG_CALLING_NAME + char *calling_name = woomera_message_header(wmsg, "local-name"); +#endif + char *presentation = woomera_message_header(wmsg, "Presentation"); + char *screening = woomera_message_header(wmsg, "Screening"); + char *rdnis = woomera_message_header(wmsg, "RDNIS"); + char *called = wmsg->callid; + char *grp = wmsg->callid; + char *p; + int tg = 0; + + if (smg_check_all_busy()) { + socket_printf(woomera->socket, + "405 SMG Server All Ckt Busy!%s", WOOMERA_RECORD_SEPERATOR); + log_printf(3, woomera->log, "SMG Server Full %d (ckt busy cnt=%i)\n", + server.call_count, server.all_ckt_busy); + return -1; + } + + log_printf(2, woomera->log, "New Call %d/%d\n", server.call_count, server.max_calls); + + if ((p = strchr(called, '/'))) { + *p = '\0'; + called = p+1; + tg = atoi(grp+1) - 1; + if (tg < 0) { + tg=0; + } + } + + woomera->trunk_group=tg; + + if (raw) { + woomera_set_raw(woomera, raw); + } + + woomera->index = add_to_holding_tank(woomera); + if (woomera->index < 1) { + socket_printf(woomera->socket, + "405 SMG Server All Tanks Busy!%s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0, woomera->log, "Error: Call Tank Full (Call Cnt=%i)\n", + server.call_count); + return -1; + } + + + woomera->index_hold = woomera->index; + + call_signal_call_init(&event, calling, called, woomera->index); + + if (presentation) { + event.calling_number_presentation = atoi(presentation); + } else { + event.calling_number_presentation = 0; + } + + if (screening) { + event.calling_number_screening_ind = atoi(screening); + } else { + event.calling_number_screening_ind = 0; + } + + if (rdnis && strlen(rdnis)) { + strncpy((char*)event.redirection_string,rdnis, + sizeof(event.redirection_string)-1); + log_printf(0,server.log,"RDNIS %s\n", rdnis); + + } + +#ifdef SMG_CALLING_NAME + if (calling_name) { + strncpy((char*)event.calling_name,calling_name, + sizeof(event.calling_name)-1); + } +#endif + + event.trunk_group = tg; + + + if (call_signal_connection_write(&server.mcon, &event) <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + socket_printf(woomera->socket, + "405 SMG Signalling Contestion!%s", + WOOMERA_RECORD_SEPERATOR); + return -1; + } + + socket_printf(woomera->socket, "100 Trying%s", WOOMERA_RECORD_SEPERATOR); + + log_printf(2, server.log, "Call Called Event [Setup ID: %d] TG=%d\n", + woomera->index,tg); + + return 0; +} + + +static void interpret_command(struct woomera_interface *woomera, struct woomera_message *wmsg) +{ + int answer = 0, media = 0, accept=0; + char *unique_id; + int cause=0; + + + if (!strcasecmp(wmsg->command, "call")) { + int err; + if (strlen(woomera->session) != 0) { + /* Call has already been placed */ + socket_printf(woomera->socket, "400 Error Call already in progress %s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0,server.log,"Woomera RX Call Even while call in progress!\n"); + return; + } + + err=handle_woomera_call_start(woomera,wmsg); + if (err) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + return; + + } else if (!strcasecmp(wmsg->command, "bye") || !strcasecmp(wmsg->command, "quit")) { + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + if (cause) { + log_printf(3, woomera->log, "Bye Cause Received: [%s]\n", cause); + } + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + log_printf(2, woomera->log, "WOOMERA CMD: Bye Received: [%s]\n", woomera->interface); + + woomera_clear_flag(woomera, WFLAG_RUNNING); + socket_printf(woomera->socket, "200 Connection closed%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + + } else if (!strcasecmp(wmsg->command, "listen")) { + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + socket_printf(woomera->socket, "405 Listener already started%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + } else { + char *event_string; + + woomera_set_flag(woomera, WFLAG_LISTENING); + add_listener(woomera); + + if (!strcmp(wmsg->callid,"MASTER")) { + woomera_set_flag(woomera, WFLAG_MASTER_DEV); + log_printf(0,woomera->log, "Starting MASTER Listen Device!\n"); + master_reset=0; + } + + + socket_printf(woomera->socket, "%s", + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "200 Listener enabled%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + if ((event_string = dequeue_event(&server.master_connection))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + event_string = NULL; + } + } + return; + + } else if ((media = !strcasecmp(wmsg->command, "debug"))) { + + int debug_level=atoi(wmsg->callid); + + if (debug_level < 10) { + server.debug=debug_level; + log_printf(0,server.log,"SMG Debugging set to %i (window=%i)\n",server.debug,server.mcon.txwindow); + } + + return; + } + + unique_id = woomera_message_header(wmsg, "Unique-Call-Id"); + if (!unique_id) { + + cause=111; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "400 Woomera cmd without uniquie id%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2,server.log,"Woomera RX Event (%s) without unique id!\n",wmsg->command); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (strlen(woomera->session) == 0) { + struct woomera_interface *session_woomera=NULL; + char *session=NULL; + int span, chan; + char ifname[100]; + /* If session does not exist this is an incoming call */ + sscanf(unique_id, "w%dg%d", &span, &chan); + span--; + chan--; + + log_printf(3, woomera->log, + "WOOMERA Got CMD %s Span=%d Chan=%d from session %s\n", + wmsg->command,span,chan,unique_id); + + if (smg_validate_span_chan(span,chan) != 0) { + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Invalid span/chan in session%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2, woomera->log, + "WOOMERA Warning invalid span chan in session %s %s\n", + wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + pthread_mutex_lock(&server.process_lock); + session = server.process_table[span][chan].session; + session_woomera = server.process_table[span][chan].dev; + + if (session_woomera) { + pthread_mutex_unlock(&server.process_lock); + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Session not found%s" + WOOMERA_RECORD_SEPERATOR); + + + log_printf(0, woomera->log, "WOOMERA Error channel in use %s %s\n", + wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (!session || strlen(session) == 0 || + strncmp(session,unique_id,sizeof(woomera->session))){ + pthread_mutex_unlock(&server.process_lock); + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Invalid/Expired Session%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(3, woomera->log, + "WOOMERA Warning: Cmd=%s with invalid session %s (orig=%s)\n", + wmsg->command,unique_id,session?session:"N/A"); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + server.process_table[span][chan].dev=woomera; + strncpy(woomera->session,unique_id,sizeof(woomera->session)); + sprintf(ifname,"w%dg%d",span+1,chan+1); + woomera_set_interface(woomera, ifname); + + woomera->span=span; + woomera->chan=chan; + + pthread_mutex_unlock(&server.process_lock); + + + log_printf(3, woomera->log, "WOOMERA Got New If=%s Session %s\n", + woomera->interface, woomera->session); + + + } else if (strncmp(woomera->session,unique_id,sizeof(woomera->session))) { + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Session Mis-match%s" + WOOMERA_RECORD_SEPERATOR); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + + if (!strcasecmp(wmsg->command, "dtmf")) { + + log_printf(3, woomera->log, "WOOMERA CMD: DTMF Received: [%s] Digit %s Body %s\n", + woomera->interface, wmsg->command_args, wmsg->body); + + wanpipe_send_dtmf(woomera,wmsg->body); + + socket_printf(woomera->socket, "200 DTMF OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "hangup")) { + + int chan = -1, span = -1; + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + span=woomera->span; + chan=woomera->chan; + + log_printf(3, woomera->log, "WOOMERA CMD: Hangup Received: [%s] MEDIA EXIST Cause=%s\n", + woomera->interface,cause); + + if (smg_validate_span_chan(span,chan) != 0) { + + socket_printf(woomera->socket, "405 No Such Channel%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + } + + + log_printf(2, woomera->log, "Hangup Received: [w%dg%d]\n", + span+1,chan+1); + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + + socket_printf(woomera->socket, "200 HANGUP OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "proceed")) { + + log_printf(3, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + socket_printf(woomera->socket, + "200 %s PROCEED OK%s" + "Unique-Call-Id: %s%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + } else if ((media = !strcasecmp(wmsg->command, "media")) || + (answer = !strcasecmp(wmsg->command, "answer")) || + (accept = !strcasecmp(wmsg->command, "accept"))) { + + handle_woomera_media_accept_answer(woomera, wmsg, media,answer,accept); + + + + } else { + log_printf(0, server.log,"WOOMERA INVALID EVENT: %s [%s] \n", + wmsg->command,wmsg->callid); + socket_printf(woomera->socket, "501 Command '%s' not implemented%s", + wmsg->command, WOOMERA_RECORD_SEPERATOR); + } +} + + +/* + EVENT INCOMING 1 + Remote-Address: 10.3.3.104 + Remote-Number: + Remote-Name: Anthony Minessale!8668630501 + Protocol: H.323 + User-Agent: Post Increment Woomera 1.0alpha1 (OpenH323 v1.17.2) 9/61 + H323-Call-Id: 887b1ff8-bb1f-da11-85c0-0007e98988c4 + Local-Number: 996 + Start-Time: Fri, 09 Sep 2005 12:25:14 -0400 + Local-Name: root +*/ + + +static void handle_call_answer(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int kill = 0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + pthread_mutex_unlock(&server.process_lock); + + if (woomera && woomera->raw) { + char callid[80]; + struct woomera_event wevent; + + if (woomera_test_flag(woomera, WFLAG_ANSWER)) { + log_printf(1, server.log, "Refusing to double-answer a call!\n"); + return; + } + + woomera_set_flag(woomera, WFLAG_ANSWER); + + if (woomera->span != event->span || woomera->chan != event->chan) { + log_printf(1, server.log, "Refusing to start media on a different channel from the one we agreed on.!\n"); + kill++; + return; + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to answer a dead call!\n"); + kill++; + } else { + int err; + err=0; + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + woomera_set_interface(woomera, callid); +#ifndef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + kill++; + } +#endif + + if (!kill) { + new_woomera_event_printf(&wevent, "EVENT CONNECT w%dg%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + } + } else { + log_printf(1, server.log, "Answer requested on non-existant session. [w%dg%d]\n", + event->span+1, event->chan+1); + kill++; + } + +#if 0 + if (kill) { + call_signal_event_t oevent; + + if (woomera) { + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* Do not hangup if this call was already hungup */ + return; + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } +#endif + +} + +static void handle_call_start_ack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + struct woomera_event wevent; + int kill = 0; + + if ((woomera = peek_from_holding_tank(event->call_setup_id))) { + char callid[80]; + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to ack a dead call!\n"); + kill++; + } else { + int err, span, chan; + + pull_from_holding_tank(event->call_setup_id,event->span,event->chan); + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + + span = event->span; + chan = event->chan; + + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + woomera_set_interface(woomera, callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[span][chan].dev = woomera; + sprintf(woomera->session,"%s-%i-%i",callid,rand(),rand()); + sprintf(server.process_table[span][chan].session,"%s-%s", + callid,woomera->session); + pthread_mutex_unlock(&server.process_lock); + + + +#ifdef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + + +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id:%s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera,WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + kill++; + } +#endif + if (!kill) { + new_woomera_event_printf(&wevent, "201 Accepted%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + new_woomera_event_printf(&wevent, "EVENT PROCEED w%dg%d%s" + "Channel-Name: g%d/%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + log_printf(2, server.log, "Call Answered Event ID = %d Device = w%dg%d!\n", + event->call_setup_id,woomera->span+1,woomera->chan+1); + } + } + } else { + log_printf(1, server.log, + "Event (START ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id, event->call_setup_id,event->span+1, event->chan+1); + kill++; + } + +#if 0 + if (kill) { + call_signal_event_t oevent; + + if (woomera) { + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* Do not hangup if this call was already hungup */ + return; + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } +#endif + +} + +static void handle_call_start_nack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int span=-1, chan=-1; + int ack=0; + + /* Always ACK the incoming NACK + * Send out the NACK ACK before pulling the TANK, because + * if we send after the pull, the outgoing call could send + * a message to boost with the pulled TANK value before + * we send a NACK ACK */ + + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + + if (event->call_setup_id > 0) { + woomera=peek_from_holding_tank(event->call_setup_id); + } + + if (woomera) { + + struct woomera_event wevent; + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); + + /* Only pull the index if we have not sent a NACK. + If NACK was already sent out we must wait for ACK + from the other side */ + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + pull_from_holding_tank(event->call_setup_id,-1,-1); + } + + isup_exec_command(0, + 0, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(0, server.log, "Event CALL START NACK on hungup call [%d]!\n", + event->call_setup_id); + } else { + + woomera_set_cause_topbx(woomera,event->release_cause); + + new_woomera_event_printf(&wevent, "EVENT HANGUP w%dg%d%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + } + + /* We already did the NACK */ + ack=0; + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + + if (woomera && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } + + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + + log_printf(2, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + if (woomera_test_flag(woomera,WFLAG_HANGUP)){ + ack++; + goto handle_call_start_nack_skip; + } + + + woomera_set_cause_topbx(woomera,event->release_cause); + + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END|WFLAG_HANGUP_NACK_ACK)); + + /* Nack Ack will be sent by the woomera thread */ + ack=0; + } else { + /* Valid state when we are not in autoacm mode */ + ack++; + log_printf(3, server.log, "Event: NACK no woomera on span chan [w%dg%d]!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(0, server.log, + "Error: Start Nack Invalid State Should not happen [%d] [w%dg%d]!\n", + event->call_setup_id, event->span+1, event->chan+1); + ack++; + } + +handle_call_start_nack_skip: + + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { + log_printf(0, server.log, "WARNING: All ckt busy!\n"); + smg_all_ckt_busy(); + } + +#warning "Ignoring CALL GAP" +#if 0 + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP) { + log_printf(0, server.log, "WARNING: Call Gapping Detected!\n"); + smg_all_ckt_gap(); + } +#endif + + if (ack) { + span=0; + chan=0; + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + isup_exec_command(span, + chan, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + + if (!woomera) { + log_printf(2, server.log, "Event (NACK ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id,event->call_setup_id, event->span+1, event->chan+1); + } + } +} + +static void handle_call_loop_start(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + + pthread_mutex_unlock(&server.process_lock); + return; + + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + + woomera=launch_woomera_loop_thread(event); + if (woomera == NULL) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + } + + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + + return; +} + +static void handle_call_start(call_signal_event_t *event) +{ + struct woomera_event wevent; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(0, server.log, + "Sent (From Handle START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg%d]\n", + event->span+1, event->chan+1); + + pthread_mutex_unlock(&server.process_lock); + return; + + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + + new_woomera_event_printf(&wevent, "EVENT INCOMING w%dg%d%s" + "Unique-Call-Id: %s%s" + "Remote-Number: %s%s" + "Remote-Name: %s%s" + "Protocol: SS7%s" + "User-Agent: sangoma_mgd%s" + "Local-Number: %s%s" + "Channel-Name: g%d/%d%s" + "Trunk-Group: %d%s" + "Presentation: %d%s" + "Screening: %d%s" + "RDNIS: %s%s" + , + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + session, + WOOMERA_LINE_SEPERATOR, + event->calling_number_digits, + WOOMERA_LINE_SEPERATOR, +#ifdef SMG_CALLING_NAME + event->calling_name, +#else + "", +#endif + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + event->called_number_digits, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + WOOMERA_LINE_SEPERATOR, + event->calling_number_presentation, + WOOMERA_LINE_SEPERATOR, + event->calling_number_screening_ind, + WOOMERA_LINE_SEPERATOR, + event->redirection_string, + WOOMERA_RECORD_SEPERATOR + ); + + if (enqueue_event_on_listeners(&wevent)) { + enqueue_event(&server.master_connection, &wevent, EVENT_KEEP_DATA); + } else { + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_BUSY); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + } + + log_printf(0, server.log, + "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } + + destroy_woomera_event_data(&wevent); + +} + +static void handle_gap_abate(call_signal_event_t *event) +{ + log_printf(0, server.log, "NOTICE: GAP Cleared!\n", + event->span+1, event->chan+1); + smg_clear_ckt_gap(); +} + +static void handle_restart_ack(call_signal_connection_t *mcon,call_signal_event_t *event) +{ + mcon->rxseq_reset =0; +} + +static void handle_call_stop(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + int ack=0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + if (woomera && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + + if (woomera_test_flag(woomera,WFLAG_HANGUP)) { + ack++; + goto handle_call_stop_skip; + } + + woomera_set_cause_topbx(woomera,event->release_cause); + + woomera_set_flag(woomera, + (WFLAG_MEDIA_END|WFLAG_HANGUP|WFLAG_HANGUP_ACK)); + + /* We have to close the socket because + At this point we are release span chan */ + +#ifdef MEDIA_SOCK_SHUTDOWN + pthread_mutex_lock(&woomera->ms_lock); + if (woomera->ms) { + log_printf(3, server.log, "Event CALL STOP [w%dg%d] closing sockets\n", + woomera->span+1,woomera->chan+1); + + close_socket(&woomera->ms->sangoma_sock); + close_socket(&woomera->ms->udp_sock); + // shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); + // shutdown(woomera->ms->udp_sock, SHUT_RDWR); + } + pthread_mutex_unlock(&woomera->ms_lock); +#endif + + log_printf(3, server.log, "Event CALL STOP on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + } else { + ack++; + } + +handle_call_stop_skip: + + if (ack) { + /* At this point we have already sent our STOP so its safe to ACK */ + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + 0); + } + + if (!woomera){ + /* This is allowed on incoming call if remote app does not answer it */ + log_printf(3, server.log, "Event CALL STOP referrs to a non-existant session [w%dg%d]!\n", + event->span+1, event->chan+1); + } +} + +static void handle_heartbeat(call_signal_event_t *event) +{ + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + } else { + int err=call_signal_connection_write(&server.mcon, event); + if (err <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + } + } + return; +} + +static void handle_call_stop_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + log_printf(2, server.log, "Stop Ack on [w%dg%d] [Setup ID: %d] [%s]!\n", + event->span+1, event->chan+1, event->call_setup_id, + woomera->interface); + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + } else { + log_printf(2, server.log, "Event CALL_STOP_ACK(%d) referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->event_id, event->span+1, event->chan+1, event->call_setup_id); + } + + /* No need for us to do any thing here */ + return; +} + + +static void handle_call_start_nack_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + if ((woomera=pull_from_holding_tank(event->call_setup_id,-1,-1))) { + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + } else { + log_printf(0, server.log, + "Event NACK ACK [w%dg%d] with valid span/chan no dev!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(2, server.log, + "Event NACK ACK referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->span+1, event->chan+1, event->call_setup_id); + } + + if (event->call_setup_id > 0) { + clear_from_holding_tank(event->call_setup_id, NULL); + } + + /* No need for us to do any thing here */ + return; +} + +#if 0 +static void validate_number(unsigned char *s) +{ + unsigned char *p; + for (p = s; *p; p++) { + if (*p < 48 || *p > 57) { + log_printf(2, server.log, "Encountered a non-numeric character [%c]!\n", *p); + *p = '\0'; + break; + } + } +} +#endif + +static int parse_ss7_event(call_signal_connection_t *mcon, call_signal_event_t *event) +{ + int ret = 0; + +#if 0 + validate_number((unsigned char*)event->called_number_digits); + validate_number((unsigned char*)event->calling_number_digits); +#endif + +#if 1 + log_printf(2, server.log, + "RX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + event->release_cause, + event->call_setup_id, + event->fseqno, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A") + ); +#endif + +#if 0 + log_printf(2, server.log, "RX EVENT\n"); + log_printf(2, server.log, "===================================\n"); + log_printf(2, server.log, " rType: %s (%0x HEX)\n", + call_signal_event_id_name(event->event_id),event->event_id); + log_printf(2, server.log, " rSpan: [%d]\n",event->span+1); + log_printf(2, server.log, " rChan: [%d]\n",event->chan+1); + log_printf(2, server.log, " rCalledNum: %s\n", + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A")); + log_printf(2, server.log, " rCallingNum: %s\n", + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")); + log_printf(2, server.log, " rCause: %d\n",event->release_cause); + log_printf(2, server.log, " rInterface: [w%dg%d]\n",event->span+1,event->chan+1); + log_printf(2, server.log, " rEvent ID: [%d]\n",event->event_id); + log_printf(2, server.log, " rSetup ID: [%d]\n",event->call_setup_id); + log_printf(2, server.log, " rSeq: [%d]\n",event->fseqno); + log_printf(2, server.log, "===================================\n"); + +#endif + +#if 0 + log_printf(2, server.log, + "\nRX EVENT\n" + "===================================\n" + " rType: %s (%0x HEX)\n" + " rSpan: [%d]\n" + " rChan: [%d]\n" + " rCalledNum: %s\n" + " rCallingNum: %s\n" + " rCause: %s\n" + " rInterface : [w%dg%d]\n" + " rEvent ID : [%d]\n" + " rSetup ID: [%d]\n" + " rSeq: [%d]\n" + "===================================\n" + "\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"), + release_to_string(event->release_cause), + event->span+1, + event->chan+1, + event->event_id, + event->call_setup_id, + event->fseqno + ); +#endif + + + switch(event->event_id) { + + case SIGBOOST_EVENT_CALL_START: + handle_call_start(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_CALL_START_ACK: + handle_call_start_ack(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK: + handle_call_start_nack(event); + break; + case SIGBOOST_EVENT_CALL_ANSWERED: + handle_call_answer(event); + break; + case SIGBOOST_EVENT_HEARTBEAT: + handle_heartbeat(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK_ACK: + handle_call_start_nack_ack(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED_ACK: + handle_call_stop_ack(event); + break; + case SIGBOOST_EVENT_INSERT_CHECK_LOOP: + handle_call_loop_start(event); + break; + case SIGBOOST_EVENT_REMOVE_CHECK_LOOP: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: + handle_restart_ack(mcon,event); + break; + case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: + handle_gap_abate(event); + break; + default: + log_printf(0, server.log, "Warning no handler implemented for [%s]\n", + call_signal_event_id_name(event->event_id)); + break; + } + + return ret; +} + + +static void *monitor_thread_run(void *obj) +{ + int ss = 0; + int policy=0,priority=0; + char a=0,b=0; + call_signal_connection_t *mcon=&server.mcon; + call_signal_connection_t *mconp=&server.mconp; + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + + if (call_signal_connection_open(mcon, + mcon->cfg.local_ip, + mcon->cfg.local_port, + mcon->cfg.remote_ip, + mcon->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCON Socket [%d] %s\n", + mcon->socket,strerror(errno)); + exit(-1); + } + + if (call_signal_connection_open(mconp, + mconp->cfg.local_ip, + mconp->cfg.local_port, + mconp->cfg.remote_ip, + mconp->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCONP Socket [%d] %s\n", + mconp->socket,strerror(errno)); + exit(-1); + } + + mcon->log = server.log; + mconp->log = server.log; + + isup_exec_command(0, + 0, + -1, + SIGBOOST_EVENT_SYSTEM_RESTART, + 0); + + mcon->rxseq_reset=1; + + smg_get_current_priority(&policy,&priority); + + log_printf(1, server.log, "Open udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + log_printf(1, server.log, "Monitor Thread Started (%i:%i)\n",policy,priority); + + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { +#if 0 + ss = waitfor_socket(server.mcon.socket, 1000, POLLERR | POLLIN); +#else + ss = waitfor_2sockets(mcon->socket, + mconp->socket, + &a, &b, 1000); +#endif + + if (ss > 0) { + + call_signal_event_t *event=NULL; + int i=0; + + if (b) { +mcon_retry_priority: + if ((event = call_signal_connection_readp(mconp,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event P [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mconp,event); + if (++i < 10) { + goto mcon_retry_priority; + } + + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost P Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + i=0; + + if (a) { +mcon_retry: + if ((event = call_signal_connection_read(mcon,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mcon,event); + + if (++i < 50) { + goto mcon_retry; + } + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + } + + if (ss < 0){ + log_printf(0, server.log, "Thread Run: Select Socket Error!\n"); + break; + } + + } + + log_printf(1, server.log, "Close udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + call_signal_connection_close(&server.mcon); + call_signal_connection_close(&server.mconp); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + log_printf(0, server.log, "Monitor Thread Ended\n"); + + return NULL; +} + +static void woomera_loop_thread_run(struct woomera_interface *woomera) +{ + int err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log, "Failed to start loop media thread\n"); + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + return; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP)) { + + sleep(1); + continue; + + } + + woomera_clear_flag(woomera, WFLAG_RUNNING); + + log_printf(2, server.log, "Woomera Session: For Loop Test exiting %s\n",woomera->interface); + + + + return; +} + +static void *woomera_thread_run(void *obj) +{ + struct woomera_interface *woomera = obj; + struct woomera_message wmsg; + struct woomera_event wevent; + char *event_string; + int mwi; + int err; + int policy=0, priority=0; + int span = -1, chan = -1; + + woomera_message_init(&wmsg); + + //smg_get_current_priority(&policy,&priority); + + log_printf(2, server.log, "WOOMERA session for started (ptr=%p : loop=%i)(%i:%i)\n", + woomera,woomera->loop_tdm,policy,priority); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_mutex_init(&woomera->queue_lock, NULL); + pthread_mutex_init(&woomera->ms_lock, NULL); + pthread_mutex_init(&woomera->dtmf_lock, NULL); + pthread_mutex_init(&woomera->vlock, NULL); + pthread_mutex_init(&woomera->flags_lock, NULL); + + if (woomera->loop_tdm) { + woomera_loop_thread_run(woomera); + goto woomera_session_close; + } + + err=socket_printf(woomera->socket, + "EVENT HELLO Sangoma Media Gateway%s" + "Supported-Protocols: TDM%s" + "Version: %s%s" + "Remote-Address: %s%s" + "Remote-Port: %d%s" + "Raw-Format: %s%s", + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + SMG_VERSION, WOOMERA_LINE_SEPERATOR, + inet_ntoa(woomera->addr.sin_addr), WOOMERA_LINE_SEPERATOR, + ntohs(woomera->addr.sin_port), WOOMERA_LINE_SEPERATOR, + server.hw_coding?"ALAW":"ULAW", WOOMERA_RECORD_SEPERATOR + ); + + if (err) { + log_printf(0, server.log, "Woomera session socket failure! (ptr=%p)\n", + woomera); + woomera_clear_flag(woomera, WFLAG_RUNNING); + goto woomera_session_close; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + woomera_test_flag(woomera, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + !master_reset) { + + + mwi = woomera_message_parse(woomera, &wmsg, WOOMERA_HARD_TIMEOUT); + if (mwi >= 0) { + + if (mwi) { + interpret_command(woomera, &wmsg); + } else if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + if (socket_printf(woomera->socket, "%s", event_string)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + free(event_string); + log_printf(4, server.log, + "WOOMERA session (ptr=%p) print string error\n", + woomera); + break; + } + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + if (woomera->timeout > 0 && time(NULL) >= woomera->timeout) { + + /* Sent the hangup only after we sent a NACK */ + + log_printf(2, server.log, + "WOOMERA session (ptr=%p) Call Timedout ! [%s] (Timeout=%d)\n", + woomera,woomera->interface,woomera->timeout); + + /* Let the Index check below send a NACK */ + if (woomera->index) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + break; + } + + } else { + log_printf(3, server.log, "WOOMERA session (ptr=%p) [%s] READ MSG Error %i \n", + woomera,woomera->interface,mwi); + break; + } + + } + +woomera_session_close: + + log_printf(2, server.log, "WOOMERA session (ptr=%p) is dying [%s]: SR=%d WR=%d WF=0x%04X\n", + woomera,woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_RUNNING), + woomera->flags); + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + usleep(100); + sched_yield(); + } + } + + + /*********************************************** + * Identify the SPAN CHAN to be used below + ***********************************************/ + + chan = woomera->chan; + span = woomera->span; + + + if (!woomera_test_flag(woomera, WFLAG_HANGUP)) { + + /* The call was not HUNGUP. This is the last check, + If the call is valid, hungup the call if the call + was never up the keep going */ + woomera_set_flag(woomera, WFLAG_HANGUP); + + if (smg_validate_span_chan(span,chan) == 0) { + + if (!woomera->index) { + + if (autoacm || woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + woomera->q931_rel_cause_tosig); + + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } else { + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_START_NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } + } else { + log_printf(0, woomera->log, "Woomera Not Sent CALL STOPPED - Instead NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + + } + }else{ + /* This can happend if an outgoing call times out + or gets hungup before it gets acked. Its not a + failure */ + if (!woomera->index) { + + /* In this case we really failed to tx STOP */ + log_printf(0, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + } + + } + +woo_re_hangup: + + + /* We must send a STOP ACK to boost telling it that we are done */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + + /* SMG received a HANGUP from boost. + We must now send back the ACK to the HANGUP. + Boost will not release channel until we + ACK the hangup */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Ack) to SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + }else{ + /* This should never happen! If it does + we broke protocol */ + log_printf(0, woomera->log, + "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_ACK); + + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + + /* SMG received a NACK from boost during call startup. + We must now send back the ACK to the NACK. + Boost will not release channel until we + ACK the NACK */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Nack Ack) to SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + + } else { + log_printf(0, woomera->log, + "FAILED: Sent (Nack Ack) SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); + + } + + if (woomera->index) { + + int index = woomera->index; + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Timeout: %ld%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + woomera->timeout, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(18), + WOOMERA_LINE_SEPERATOR, + 18, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + + if (peek_from_holding_tank(index)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(0, + 0, + index, + SIGBOOST_EVENT_CALL_START_NACK, + 0); + + log_printf(2, woomera->log, + "Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] .. WAITING FOR NACK ACK\n", + index); + } + + } + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent NACK to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //30sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] ... \n", + index); + } + + if (overall_cnt > 10) { //300sec timeotu + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + break; + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { + break; + } + + usleep(5000); + sched_yield(); + } + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", + index); + + } else { + log_printf(2, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", + index); + + } + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent HANGUP to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + log_printf(2, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //10sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i] ... \n", + woomera->interface,woomera->index_hold); + } + + if (overall_cnt > 10) { //100sec + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + server.process_table[span][chan].dev != woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + usleep(5000); + sched_yield(); + } + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + } else { + log_printf(2, woomera->log, + "Wait GOT STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + } + } + + /***************************************************** + * We must wait for WFLAG_WAIT_FOR_STOPPED_ACK here + * so that STOP_ACK can access the woomera + *****************************************************/ + + if (smg_validate_span_chan(span,chan) == 0) { + log_printf(2, woomera->log, + "WOOMERA Clearing Processs Table ... \n", + woomera->interface); + pthread_mutex_lock(&server.process_lock); + if (server.process_table[span][chan].dev == woomera){ + server.process_table[span][chan].dev = NULL; + memset(server.process_table[span][chan].session,0,SMG_SESSION_NAME_SZ); + } + pthread_mutex_unlock(&server.process_lock); + } + +#if 0 +//Used for testing + if (1) { + int chan = woomera->chan; + int span = woomera->span; + if (smg_validate_span_chan(span,chan) == 0) { + pthread_mutex_lock(&server.process_lock); + /* This is possible in case media thread dies on startup */ + + if (server.process_table[span][chan]){ + log_printf(0, server.log, + "Sanity Span Chan Still in use: [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + //server.process_table[span][chan] = NULL; + } + pthread_mutex_unlock(&server.process_lock); + } + } +#endif + + usleep(3000000); + + /* Sanity Check */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP ACK\n"); + goto woo_re_hangup; + } + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP NACK ACK\n"); + goto woo_re_hangup; + } + + /* This is where we actually pull the index + * out of the tank. We had to keep the tank + * value until the end of the call. Tank is only + * used on outgoing calls. */ + if (woomera->index_hold >= 1) { + clear_from_holding_tank(woomera->index_hold, woomera); + woomera->index_hold=0; + } + + log_printf(2, woomera->log, "Woomera Thread Finished %u\n", (unsigned long) woomera->thread); + close_socket(&woomera->socket); + woomera->socket=-1; + + /* delete queue */ + while ((event_string = dequeue_event(woomera))) { + free(event_string); + } + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + del_listener(woomera); + } + + log_printf(2, server.log, "WOOMERA session for [%s] stopped (ptr=%p)\n", + woomera->interface,woomera); + + if (woomera_test_flag(woomera, WFLAG_MASTER_DEV)) { + log_printf(0,server.log,"MASTER Thread Stopped (ptr=%p)\n",woomera); + master_reset=0; + } + + + pthread_mutex_destroy(&woomera->queue_lock); + pthread_mutex_destroy(&woomera->ms_lock); + pthread_mutex_destroy(&woomera->dtmf_lock); + pthread_mutex_destroy(&woomera->vlock); + pthread_mutex_destroy(&woomera->flags_lock); + woomera_set_raw(woomera, NULL); + woomera_set_interface(woomera, NULL); + + woomera_message_clear(&wmsg); + + free(woomera); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count--; + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_exit(NULL); + return NULL; +} + + +static int launch_woomera_thread(struct woomera_interface *woomera) +{ + int result = 0; + pthread_attr_t attr; + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_RUNNING); + result = pthread_create(&woomera->thread, &attr, woomera_thread_run, woomera); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! (%i) %s\n", + __FUNCTION__,result,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + +static int launch_monitor_thread(void) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 10; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + log_printf(0,server.log,"%s: Old Priority =%i res=%i \n",__FUNCTION__, + param.sched_priority,result); + + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + result = pthread_create(&server.monitor_thread, &attr, monitor_thread_run, NULL); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +#ifdef WP_HPTDM_API +static void *hp_tdmapi_span_run(void *obj) +{ + hp_tdm_api_span_t *span = obj; + int err; + + log_printf(0,server.log,"Starting %s span!\n",span->ifname); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + if (!span->run_span) { + break; + } + + err = span->run_span(span); + if (err) { + break; + } + + } + + if (span->close_span) { + span->close_span(span); + } + + sleep(3); + log_printf(0,server.log,"Stopping %s span!\n",span->ifname); + + pthread_exit(NULL); +} + + +static int launch_hptdm_api_span_thread(int span) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 5; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + result = pthread_create(&server.monitor_thread, &attr, hp_tdmapi_span_run, &hptdmspan[span]); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + } + pthread_attr_destroy(&attr); + + return result; +} +#endif + +static int configure_server(void) +{ + struct woomera_config cfg; + char *var, *val; + int cnt = 0; + + server.dtmf_intr_ch = -1; + + if (!woomera_open_file(&cfg, server.config_file)) { + log_printf(0, server.log, "open of %s failed\n", server.config_file); + return 0; + } + + while (woomera_next_pair(&cfg, &var, &val)) { + if (!strcasecmp(var, "boost_local_ip")) { + strncpy(server.mcon.cfg.local_ip, val, + sizeof(server.mcon.cfg.local_ip) -1); + strncpy(server.mconp.cfg.local_ip, val, + sizeof(server.mconp.cfg.local_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_local_port")) { + server.mcon.cfg.local_port = atoi(val); + server.mconp.cfg.local_port = + server.mcon.cfg.local_port+1; + cnt++; + } else if (!strcasecmp(var, "boost_remote_ip")) { + strncpy(server.mcon.cfg.remote_ip, val, + sizeof(server.mcon.cfg.remote_ip) -1); + strncpy(server.mconp.cfg.remote_ip, val, + sizeof(server.mconp.cfg.remote_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_remote_port")) { + server.mcon.cfg.remote_port = atoi(val); + server.mconp.cfg.remote_port = + server.mcon.cfg.remote_port+1; + cnt++; + } else if (!strcasecmp(var, "logfile_path")) { + if (!server.logfile_path) { + server.logfile_path = strdup(val); + } + } else if (!strcasecmp(var, "woomera_port")) { + server.port = atoi(val); + } else if (!strcasecmp(var, "debug_level")) { + server.debug = atoi(val); + } else if (!strcasecmp(var, "out_tx_test")) { + server.out_tx_test = atoi(val); + } else if (!strcasecmp(var, "loop_trace")) { + server.loop_trace = atoi(val); + } else if (!strcasecmp(var, "rxgain")) { + server.rxgain = atoi(val); + } else if (!strcasecmp(var, "txgain")) { + server.txgain = atoi(val); + } else if (!strcasecmp(var, "dtmf_on_duration")){ + server.dtmf_on = atoi(val); + } else if (!strcasecmp(var, "dtmf_off_duration")){ + server.dtmf_off = atoi(val); + } else if (!strcasecmp(var, "dtmf_inter_ch_duration")){ + server.dtmf_intr_ch = atoi(val); + } else if (!strcasecmp(var, "max_calls")) { + int max = atoi(val); + if (max > 0) { + server.max_calls = max; + } + } else if (!strcasecmp(var, "autoacm")) { + int max = atoi(val); + if (max >= 0) { + autoacm=max; + } + + } else if (!strcasecmp(var, "media_ip")) { + strncpy(server.media_ip, val, sizeof(server.media_ip) -1); + } else { + log_printf(0, server.log, "Invalid Option %s at line %d!\n", var, cfg.lineno); + } + } + + /* Post initialize */ + if (server.dtmf_on == 0){ + server.dtmf_on=SMG_DTMF_ON; + } + if (server.dtmf_off == 0) { + server.dtmf_off=SMG_DTMF_OFF; + } + if (server.dtmf_intr_ch == -1) { + server.dtmf_intr_ch = 0; + } + server.dtmf_size=(server.dtmf_on+server.dtmf_off)*10*2; + + log_printf(0,server.log, "DTMF On=%i Off=%i IntrCh=%i Size=%i\n", + server.dtmf_on,server.dtmf_off,server.dtmf_intr_ch,server.dtmf_size); + + woomera_close_file(&cfg); + return cnt == 4 ? 1 : 0; +} + + + +static int main_thread(void) +{ + + struct sockaddr_in sock_addr, client_addr; + struct woomera_interface *new_woomera; + int client_sock = -1, pid = 0; + unsigned int len = 0; + FILE *tmp; + + if ((server.master_connection.socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + log_printf(0, server.log, "socket() failed\n"); + return 1; + } + + memset(&sock_addr, 0, sizeof(sock_addr)); /* Zero out structure */ + sock_addr.sin_family = AF_INET; /* Internet address family */ + sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + sock_addr.sin_port = htons(server.port); /* Local port */ + + /* Bind to the local address */ + if (bind(server.master_connection.socket, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0) { + log_printf(0, server.log, "bind(%d) failed\n", server.port); + return 1; + } + + /* Mark the socket so it will listen for incoming connections */ + if (listen(server.master_connection.socket, MAXPENDING) < 0) { + log_printf(0, server.log, "listen() failed\n"); + return 1; + } + + if ((pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "pid %d already exists.\n", pid); + exit(0); + } + + if (!(tmp = safe_fopen(PIDFILE, "w"))) { + log_printf(0, stderr, "Error creating pidfile %s\n", PIDFILE); + return 1; + } else { + fprintf(tmp, "%d", getpid()); + fclose(tmp); + tmp = NULL; + } + + no_nagle(server.master_connection.socket); + +#if 0 + if (1) { + int span,chan; + call_signal_event_t event; +#if 0 + span=1; + chan=30; + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); +#else + for (span=0;span<8;span++) { + for (chan=0;chan<31;chan++) { + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); + } + } +#endif + } +#endif + +#ifdef WP_HPTDM_API + if (1) { + int span; + for (span=0;span<16;span++) { + hptdmspan[span] = sangoma_hptdm_api_span_init(span); + if (!hptdmspan[span]) { + break; + } else { + log_printf(0, server.log, "HP TDM API Span: %d configured...\n", + span); + launch_hptdm_api_span_thread(span); + } + } + } +#endif + + log_printf(1, server.log, "Main Process Started: Woomera Ready port: %d\n", server.port); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + /* Set the size of the in-out parameter */ + len = sizeof(client_addr); + + /* Wait for a client to connect */ + if ((client_sock = accept(server.master_connection.socket, (struct sockaddr *) &client_addr, &len)) < 0) { + log_printf(0, server.log, "accpet() failed\n"); + return 1; + } + + if ((new_woomera = new_woomera_interface(client_sock, &client_addr, len))) { + log_printf(2, server.log, "Starting Thread for New Connection %s:%d Sock=%d\n", + inet_ntoa(new_woomera->addr.sin_addr), + ntohs(new_woomera->addr.sin_port), + client_sock); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count++; + pthread_mutex_unlock(&server.thread_count_lock); + if (launch_woomera_thread(new_woomera)) { + socket_printf(new_woomera->socket, + "501 call was cancelled!%s", + WOOMERA_RECORD_SEPERATOR); + + close_socket(&new_woomera->socket); + new_woomera->socket=-1; + free(new_woomera); + } + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + } + } + + log_printf(1, server.log, "Main Process End\n"); + + return 0; +} + +static int do_ignore(int sig) +{ + return 0; +} + +static int do_shut(int sig) +{ + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + close_socket(&server.master_connection.socket); + log_printf(1, server.log, "Caught SIG %d, Closing Master Socket!\n", sig); + return 0; +} + +static int sangoma_tdm_init (int span) +{ +#ifdef LIBSANGOMA_GET_HWCODING + wanpipe_tdm_api_t tdm_api; + int fd=sangoma_open_tdmapi_span(span); + if (fd < 0 ){ + return -1; + } else { + server.hw_coding=sangoma_tdm_get_hw_coding(fd,&tdm_api); + close_socket(&fd); + } +#else +#error "libsangoma missing hwcoding feature: not up to date!" +#endif + return 0; +} + + +static int woomera_startup(int argc, char **argv) +{ + int x = 0, pid = 0, bg = 0; + char *cfg=NULL, *debug=NULL, *arg=NULL; + + while((arg = argv[x++])) { + + if (!strcasecmp(arg, "-hup")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGHUP); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-term") || !strcasecmp(arg, "--term")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGTERM); + unlink(PIDFILE); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-version")) { + fprintf(stdout, "\nSangoma Media Gateway: Version %s\n\n", SMG_VERSION); + exit(0); + + } else if (!strcasecmp(arg, "-help")) { + fprintf(stdout, "%s\n%s [-help] | [ -version] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(0); + } else if (!strcasecmp(arg, "-wipe")) { + unlink(PIDFILE); + } else if (!strcasecmp(arg, "-bg")) { + bg = 1; + + } else if (!strcasecmp(arg, "-g")) { + coredump = 1; + + } else if (!strcasecmp(arg, "-debug")) { + if (argv[x] && *(argv[x]) != '-') { + debug = argv[x++]; + } + } else if (!strcasecmp(arg, "-cfg")) { + if (argv[x] && *(argv[x]) != '-') { + cfg = argv[x++]; + } + } else if (!strcasecmp(arg, "-log")) { + if (argv[x] && *(argv[x]) != '-') { + server.logfile_path = strdup(argv[x++]); + } + } else if (*arg == '-') { + log_printf(0, stderr, "Unknown Option %s\n", arg); + fprintf(stdout, "%s\n%s [-help] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(1); + } + } + + if (1){ + int spn; + for (spn=1;spn<=WOOMERA_MAX_SPAN;spn++) { + if (sangoma_tdm_init(spn) == 0) { + break; + } + } + if (spn>WOOMERA_MAX_SPAN) { + printf("\nError: Failed to access a channel on spans 1-16\n"); + printf(" Please start Wanpipe TDM API drivers\n"); + return 0; + } + } + + if (bg && (pid = fork())) { + log_printf(0, stderr, "Backgrounding!\n"); + return 0; + } + + q931_cause_setup(); + + server.port = 42420; + server.debug = 0; + strcpy(server.media_ip, "127.0.0.1"); + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + server.log = stdout; + server.master_connection.socket = -1; + server.master_connection.event_queue = NULL; + server.config_file = cfg ? cfg : "/etc/sangoma_mgd.conf"; + pthread_mutex_init(&server.listen_lock, NULL); + pthread_mutex_init(&server.ht_lock, NULL); + pthread_mutex_init(&server.process_lock, NULL); + pthread_mutex_init(&server.media_udp_port_lock, NULL); + pthread_mutex_init(&server.thread_count_lock, NULL); + pthread_mutex_init(&server.master_connection.queue_lock, NULL); + pthread_mutex_init(&server.master_connection.flags_lock, NULL); + pthread_mutex_init(&server.mcon.lock, NULL); + server.master_connection.chan = -1; + server.master_connection.span = -1; + + if (!configure_server()) { + log_printf(0, server.log, "configuration failed!\n"); + return 0; + } + +#ifndef USE_SYSLOG + if (server.logfile_path) { + if (!(server.log = safe_fopen(server.logfile_path, "a"))) { + log_printf(0, stderr, "Error setting logfile %s!\n", server.logfile_path); + server.log = stderr; + return 0; + } + } +#endif + + + if (debug) { + server.debug = atoi(debug); + } + + if (coredump) { + struct rlimit l; + memset(&l, 0, sizeof(l)); + l.rlim_cur = RLIM_INFINITY; + l.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_CORE, &l)) { + log_printf(0, stderr, "Warning: Failed to disable core size limit: %s\n", + strerror(errno)); + } + } + +#ifdef __LINUX__ + if (geteuid() && coredump) { + if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { + log_printf(0, stderr, "Warning: Failed to disable core size limit for non-root: %s\n", + strerror(errno)); + } + } +#endif + + + + (void) signal(SIGINT,(void *) do_shut); + (void) signal(SIGPIPE,(void *) do_ignore); + (void) signal(SIGHUP,(void *) do_shut); + + + woomera_set_flag(&server.master_connection, WFLAG_RUNNING); + if (launch_monitor_thread()) { + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + return 0; + } + + fprintf(stderr, "%s", WELCOME_TEXT); + log_printf(0, stderr, "Woomera STARTUP Complete. [AutoACM=%i]\n",autoacm); + + return 1; +} + +static int woomera_shutdown(void) +{ + char *event_string; + int told = 0, loops = 0; + + close_socket(&server.master_connection.socket); + pthread_mutex_destroy(&server.listen_lock); + pthread_mutex_destroy(&server.ht_lock); + pthread_mutex_destroy(&server.process_lock); + pthread_mutex_destroy(&server.media_udp_port_lock); + pthread_mutex_destroy(&server.thread_count_lock); + pthread_mutex_destroy(&server.master_connection.queue_lock); + pthread_mutex_destroy(&server.master_connection.flags_lock); + pthread_mutex_destroy(&server.mcon.lock); + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + + + if (server.logfile_path) { + free(server.logfile_path); + server.logfile_path = NULL; + } + + /* delete queue */ + while ((event_string = dequeue_event(&server.master_connection))) { + free(event_string); + } + + while(server.thread_count > 0) { + loops++; + + if (loops % 1000 == 0) { + told = 0; + } + + if (loops > 10000) { + log_printf(0, server.log, "Red Alert! threads did not stop\n"); + assert(server.thread_count == 0); + } + + if (told != server.thread_count) { + log_printf(1, server.log, "Waiting For %d thread%s.\n", + server.thread_count, server.thread_count == 1 ? "" : "s"); + told = server.thread_count; + } + ysleep(10000); + } + unlink(PIDFILE); + log_printf(0, stderr, "Woomera SHUTDOWN Complete.\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + + mlockall(MCL_FUTURE); + + + server.hw_coding=0; + + openlog (ps_progname ,LOG_PID, LOG_LOCAL2); + + if (! (ret = woomera_startup(argc, argv))) { + exit(0); + } + ret = main_thread(); + + woomera_shutdown(); + + return ret; +} + +/** EMACS ** + * Local variables: + * mode: C + * c-basic-offset: 4 + * End: + */ + diff --git a/ssmg/sangoma_mgd.trunk/Changelog b/ssmg/sangoma_mgd.trunk/Changelog deleted file mode 100644 index 385d189..0000000 --- a/ssmg/sangoma_mgd.trunk/Changelog +++ /dev/null @@ -1,187 +0,0 @@ -sangoma_mgd.c -====================================== -Jun 13 2007 - -v1.13 Nenad Corbic - Woomera OPAL Dialect - Added Congestion control - Added SCTP - Added priority ISUP queue - Fixed presentation - -v1.12 Nenad Corbic - Fixed CCR - Removed socket shutdown on end call. - Let Media thread shutodwn sockets. - -v1.11 Nenad Corbic - Fixed Remote asterisk/woomera connection - Increased socket timeouts - - -chan_woomera.c -====================================== -Jun 13 2007 - -v1.11 Nenad Corbic - Updated multiple profiles - Updated Dialect for OPAL Woomera - Added call logging/debugging - Fixed presentation - -v1.10 Nenad Corbic - Bug fix in incoming hangup - -v1.9 Nenad Corbic - Fixed remote asterisk/woomera - setup. - - -sangoma_mgd.c -====================================== -May 2 2007 - -v1.10 Nenad Corbic - Added Woomera OPAL dialect. - Start montor thread in priority - -v1.9 Nenad Corbic - Added Loop mode for ccr - Added remote debug enable - Fixed syslog logging. - -v1.8 Nenad Corbic - Added a ccr loop mode for each channel. - Boost can set any channel in loop mode - - -chan_woomera.c -===================================== -May 2 2007 - -v1.8 Nenad Corbic - Added Woomera OPAL dialect. - Code cleanup. - Added cli call_status - -v1.7 Nenad Corbic - Added smgdebug to enable smg debugging - Added rdnis - - -sangoma_mgd.c -===================================== -v1.7 Dec 11 2006 - - -Nenad Corbic - -Pass trunk group number to incoming call -chan woomera will use it to append to context -name. - -Added presentation feature. - - -chan_woomera.c -====================================== -v1.6 Dec 11 2006 - -Nenad Corbic - -Added incoming trunk group context -The trunk number will be added to the -profile context name. - -Added presentation feature. - -Added CODING option in woomera.conf to indicate -coding for rx/tx gain on initialization. - - - -sangoma_mgd.c -===================================== -v1.6 Nov 15 2006 - -Nenad Corbic - -Only rx/tx ULAW and ALAW from TDM API. -This greatly reduces system usage, since -two times less traffic passes from -kerel to user space layer. - -The G.711 transcoding is done in asterisk, -there is no benefit in the kernel. - -Removed rxgain/txgain from SMG. - - - -chan_woomera.c -====================================== -v1.5 Nov 15 2006 - -Nenad Corbic - -chan_woomera support for SLINEAR/ULAW/ALAW -voice formats. The codec used is autodetected from SMG. -This option greatly improves system performace -because ulaw/alaw traffic is two times smaller than -SLIN. Resulting in less network traffic. - -Added rxgain and txgain to woomera.conf -Also rxgain and txgain can be globaly changed -from CLI. - -CLI> woomera rxgain 1.0 -CLI> woomera txgain 1.0 - - -sangoma_mgd.c -====================================== -v1.5 Nov 9 2006 - -Nenad Corbic - -Bug fix in START_NACK_ACK handling. ----------------------------------- - -When we receive START_NACK we must alwasy pull tank before -we send out NACK_ACK this way we will not try to send NACK -ourself. - - -New RX/TX Gain options ----------------------- - -In /etc/sangoma_mgd.conf - rxgain=>0 - txgain=>0 - -These optinos can be used to adjust -rx tx gain. Thes options are identical to -zaptel options in zapata.conf. - - - -chan_woomera.c -====================================== -v.1.4 Nov 2006 - -Nenad Corbic - -Added the woomera panic option to gracefully stop -all calls. - -CLI> woomera panic 10 - -This command will completely gracefully stop all calls -and it will disable woomera. - -After this point one can gracefully unload woomera module. - -CLI> unload chan_woomera.so - - - diff --git a/ssmg/sangoma_mgd.trunk/Changelog.sangoma_mgd b/ssmg/sangoma_mgd.trunk/Changelog.sangoma_mgd new file mode 100644 index 0000000..998bae2 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/Changelog.sangoma_mgd @@ -0,0 +1,112 @@ +sangoma_mgd.c +====================================== +Jan 18 2007 + * v1.26 Nenad Corbic + * Fixed hangup after invalid Answer or Ack Session + * Can cause double use of setup id - now fixed + * +Dec 31 2007 + * v1.25 Nenad Corbic + * Removed UDP Resync it can cause skb_over errors. + * Moved RDNIS message to higher debug level + +Nov 30 2007 + * v1.24 Nenad Corbic + * Bug fix on return code on ALL ckt busy + * + +Nov 28 2007 + + * v1.23 Nenad Corbic + * Bug fix on socket open. Check for retun code >= 0 + * + + * v1.22 Nenad Corbic + * Nov 27 2007 + * Updated DTMF Tx function + * Fixed - dtmf tx without voice + * Fxied - dtmf clipping. + + +Nov 22 2007 + + * v1.21 Nenad Corbic + * Major unit testing of each state + * Numerous bug fixes for non autoacm mode. + * Changed "Channel-Name" to tg/cic + * Added compile option WANPIPE_CHAN_NAME to change Asterisk channel + * name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE}) + * instead of WOOMERA (for example) + * + * v1.20 Nenad Corbic + * Added option for Auto ACM response mode. + * + * v1.19 Nenad Corbic + * Configurable DTMF + * Bug fix in release codes (all ckt busy) + * + * v1.18 Nenad Corbic + * Added new rel cause support based on + * digits instead of strings. + * + * v1.17 Nenad Corbic + * Added session support + * + * v1.16 Nenad Corbic + * Added hwec disable on loop ccr + * + * v1.15 Nenad Corbic + * Updated DTMF Locking + * Added delay between digits + * + * v1.14 Nenad Corbic + * Updated DTMF Library + * Fixed DTMF synchronization + * + * v1.13 Nenad Corbic + * Woomera OPAL Dialect + * Added Congestion control + * Added SCTP + * Added priority ISUP queue + * Fixed presentation + * + * v1.12 Nenad Corbic + * Fixed CCR + * Removed socket shutdown on end call. + * Let Media thread shutodwn sockets. + * + * v1.11 Nenad Corbic + * Fixed Remote asterisk/woomera connection + * Increased socket timeouts + * + * v1.10 Nenad Corbic + * Added Woomera OPAL dialect. + * Start montor thread in priority + * + * v1.9 Nenad Corbic + * Added Loop mode for ccr + * Added remote debug enable + * Fixed syslog logging. + * + * v1.8 Nenad Corbic + * Added a ccr loop mode for each channel. + * Boost can set any channel in loop mode + * + * v1.7 Nenad Corbic + * Pass trunk group number to incoming call + * chan woomera will use it to append to context + * name. Added presentation feature. + * name. Added presentation feature. + * + * v1.6 Nenad Corbic + * Use only ALAW and MLAW not SLIN. + * This reduces the load quite a bit. + * Send out ALAW/ULAW format on HELLO message. + * RxTx Gain is done now in chan_woomera. + * + * v1.5 Nenad Corbic + * Bug fix in START_NACK_ACK handling. + * When we receive START_NACK we must alwasy pull tank before + * we send out NACK_ACK this way we will not try to send NACK + * ourself. + diff --git a/ssmg/sangoma_mgd.trunk/Makefile b/ssmg/sangoma_mgd.trunk/Makefile index adad9f1..9ee014c 100644 --- a/ssmg/sangoma_mgd.trunk/Makefile +++ b/ssmg/sangoma_mgd.trunk/Makefile @@ -30,10 +30,11 @@ ifndef KINSTDIR endif CC = gcc +INSTALLPREFIX= INCLUDES = -I$(KDIR)/include -I ../../ssmg/libsangoma.trunk -I. -I ../../patches/kdrivers/include -I ../../patches/kdrivers/wanec/oct6100_api/include -I ../../patches/kdrivers/wanec -I/usr/local/include -I../../patches/kdrivers/include -I/usr/include/wanpipe -Ilib/libteletone/src -CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 +CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm @@ -47,7 +48,7 @@ endif all: sangoma_mgd libs: - $(shell cd lib/libteletone; ./configure; cd ../../; ) + $(shell cd lib/libteletone; ./configure --prefix=$(INSTALLPREFIX); cd ../../; ) $(MAKE) -C lib/libteletone all switch_buffer.o: switch_buffer.c switch_buffer.h @@ -79,23 +80,20 @@ install_smg: old_cleanup @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ install -D -m 755 sangoma_mgd.conf.sample $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ fi +ifeq "${NO_SS7}" "YES" + @echo"SS7 control and service script not installed" +else install -D -m 755 smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/etc/init.d/smgss7_init_ctrl + install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/usr/sbin/smgss7_init_ctrl +endif @echo "sangoma_mgd Installed" old_cleanup: ./scripts/old_cleanup.sh -install_woomera: - install -D -m 755 chan_woomera.so $(INSTALLPREFIX)/usr/lib/asterisk/modules/chan_woomera.so - @if [ ! -e $(INSTALLPREFIX)/etc/asterisk/woomera.conf ]; then \ - install -D -m 755 woomera.conf $(INSTALLPREFIX)/etc/asterisk/woomera.conf; \ - fi - @echo "chan_woomera Installed" - - -install_all: all install_smg install_woomera +install_all: all install_smg uninstall: /bin/rm $(INSTALLPREFIX)/usr/sbin/sangoma_mgd $(INSTALLPREFIX)/etc/sangoma_mgd.conf diff --git a/ssmg/sangoma_mgd.trunk/app/.svn/entries b/ssmg/sangoma_mgd.trunk/app/.svn/entries index d6197ef..12e5d3b 100644 --- a/ssmg/sangoma_mgd.trunk/app/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/app/.svn/entries @@ -1,7 +1,7 @@ 8 dir -24 +58 https://www.sangomapbx.com:/svn/sangoma_mgd/trunk/app https://www.sangomapbx.com:/svn/sangoma_mgd diff --git a/ssmg/sangoma_mgd.trunk/call_signal.c b/ssmg/sangoma_mgd.trunk/call_signal.c index 3d39f12..5e28542 100644 --- a/ssmg/sangoma_mgd.trunk/call_signal.c +++ b/ssmg/sangoma_mgd.trunk/call_signal.c @@ -116,6 +116,9 @@ int call_signal_connection_open(call_signal_connection_t *mcon, char *local_ip, call_signal_event_t *call_signal_connection_read(call_signal_connection_t *mcon, int iteration) { unsigned int fromlen = sizeof(struct sockaddr_in); +#if 0 + call_signal_event_t *event = &mcon->event; +#endif int bytes = 0; bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, @@ -135,6 +138,7 @@ call_signal_event_t *call_signal_connection_read(call_signal_connection_t *mcon, return NULL; } + mcon->txwindow = mcon->txseq - mcon->event.bseqno; mcon->rxseq++; if (mcon->rxseq != mcon->event.fseqno) { @@ -146,8 +150,24 @@ call_signal_event_t *call_signal_connection_read(call_signal_connection_t *mcon, clog_printf(0, mcon->log, "------------------------------------------\n"); } + +#if 0 +/* Debugging only not to be used in production because span/chan can be invalid */ + if (mcon->event.span < 0 || mcon->event.chan < 0 || mcon->event.span > 16 || mcon->event.chan > 31) { + clog_printf(0, mcon->log, + "------------------------------------------\n"); + clog_printf(0, mcon->log, + "Critical Error: RX Cmd=%s Invalid Span=%i Chan=%i\n", + call_signal_event_id_name(event->event_id), event->span,event->chan); + clog_printf(0, mcon->log, + "------------------------------------------\n"); + + errno=EAGAIN; + return NULL; + } +#endif + - mcon->txwindow = mcon->txseq - mcon->event.bseqno; return &mcon->event; @@ -169,6 +189,9 @@ call_signal_event_t *call_signal_connection_read(call_signal_connection_t *mcon, call_signal_event_t *call_signal_connection_readp(call_signal_connection_t *mcon, int iteration) { unsigned int fromlen = sizeof(struct sockaddr_in); +#if 0 + call_signal_event_t *event = &mcon->event; +#endif int bytes = 0; bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, @@ -176,6 +199,23 @@ call_signal_event_t *call_signal_connection_readp(call_signal_connection_t *mcon if (bytes == sizeof(mcon->event) || bytes == (sizeof(mcon->event)-sizeof(uint32_t))) { + +#if 0 + /* Debugging only not to be used in production because span/chan can be invalid */ + if (mcon->event.span < 0 || mcon->event.chan < 0 || mcon->event.span > 16 || mcon->event.chan > 31) { + clog_printf(0, mcon->log, + "------------------------------------------\n"); + clog_printf(0, mcon->log, + "Critical Error: RXp Cmd=%s Invalid Span=%i Chan=%i\n", + call_signal_event_id_name(event->event_id), event->span,event->chan); + clog_printf(0, mcon->log, + "------------------------------------------\n"); + + errno=EAGAIN; + return NULL; + } +#endif + return &mcon->event; } else { if (iteration == 0) { @@ -205,7 +245,7 @@ int call_signal_connection_write(call_signal_connection_t *mcon, call_signal_eve clog_printf(0, mcon->log, "------------------------------------------\n"); clog_printf(0, mcon->log, - "Critical Error: Cmd=%s Invalid Span=%i Chan=%i\n", + "Critical Error: TX Cmd=%s Invalid Span=%i Chan=%i\n", call_signal_event_id_name(event->event_id), event->span,event->chan); clog_printf(0, mcon->log, "------------------------------------------\n"); diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.pbxdir b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.pbxdir index 4d2816d..aa0d569 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.pbxdir +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.pbxdir @@ -1 +1 @@ -/usr/src/asterisk +/usr/src/ast1.4/asterisk-1.4.11 diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/all-wcprops b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/all-wcprops index 4a29419..870dcc0 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/all-wcprops +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/all-wcprops @@ -1,13 +1,13 @@ K 25 svn:wc:ra_dav:version-url -V 34 -/svn/chan_woomera/!svn/ver/6/trunk +V 35 +/svn/chan_woomera/!svn/ver/35/trunk END chan_woomera.c K 25 svn:wc:ra_dav:version-url -V 49 -/svn/chan_woomera/!svn/ver/6/trunk/chan_woomera.c +V 50 +/svn/chan_woomera/!svn/ver/36/trunk/chan_woomera.c END g711.h K 25 @@ -15,17 +15,23 @@ svn:wc:ra_dav:version-url V 41 /svn/chan_woomera/!svn/ver/1/trunk/g711.h END +Changelog.chan_woomera +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/chan_woomera/!svn/ver/35/trunk/Changelog.chan_woomera +END Makefile K 25 svn:wc:ra_dav:version-url -V 43 -/svn/chan_woomera/!svn/ver/3/trunk/Makefile +V 44 +/svn/chan_woomera/!svn/ver/29/trunk/Makefile END README K 25 svn:wc:ra_dav:version-url -V 41 -/svn/chan_woomera/!svn/ver/1/trunk/README +V 42 +/svn/chan_woomera/!svn/ver/14/trunk/README END woomera.conf K 25 diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/entries b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/entries index 7e7ce38..ef0ef3d 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/entries @@ -1,14 +1,14 @@ 8 dir -6 +35 https://www.sangomapbx.com:/svn/chan_woomera/trunk https://www.sangomapbx.com:/svn/chan_woomera -2007-10-02T20:33:46.624857Z -6 +2007-12-27T20:02:22.474001Z +35 ncorbic @@ -28,14 +28,14 @@ b26a191e-ab3a-0410-a271-b1e04e243bf1 chan_woomera.c file +36 - -2007-10-07T16:40:41.000000Z -7dcba9f7acaf61774093ca6b7fb3d102 -2007-10-02T20:33:46.624857Z -6 +2008-01-02T15:37:24.000000Z +89e6106f6033f3664d7e1f7a0136a9fb +2008-01-02T15:34:17.744631Z +36 ncorbic g711.h @@ -50,16 +50,28 @@ file 1 root +Changelog.chan_woomera +file + + + + +2007-12-31T16:40:05.000000Z +8ea889f5c578c76386df2e6b225856f7 +2007-12-27T20:02:22.474001Z +35 +ncorbic + Makefile file -2007-09-24T19:55:33.000000Z -35ea632f9ff5e91d3fdf5c9f2208f138 -2007-09-24T18:47:53.807908Z -3 +2007-12-20T17:31:49.000000Z +39268f5baaa58f6391cba2f506e41f18 +2007-12-18T20:11:15.703141Z +29 ncorbic README @@ -68,11 +80,11 @@ file -2007-09-21T20:31:17.000000Z -54d0bdf8090399a87acea5a0ab986d7d -2007-09-21T20:29:00.887216Z -1 -root +2007-11-26T01:25:59.000000Z +6b44396eddae33cda9cdb078e5030a1f +2007-10-30T20:04:39.055688Z +14 +svnanon woomera.conf file diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Changelog.chan_woomera.svn-base b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Changelog.chan_woomera.svn-base new file mode 100644 index 0000000..8c43ac5 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Changelog.chan_woomera.svn-base @@ -0,0 +1,85 @@ +chan_woomera.c +====================================== + +Dec 27 2007 + * v1.21 David Yat Sin + * Support for language + +Dec 20 2007 + * v1.20 David Yat Sin + * Support for call confirmation + * Support for default context + +Nov 30 2007 + * v1.19 Nenad Corbic + * Updated for latest CallWeaver + * Updated smgversion update on master socket + * restart. + +Nov 22 2007 + + * v1.18 Nenad Corbic + * Updated Channel-Name on outbound call + * Check queued events on ABORT + * Major Unit Testing done + * Ability to change chan name from Makefile + * + * v1.17 Nenad Corbic + * Updates for Asterisk 1.4 + * Updated the release causes + * Updated for tech_indication + * + * v1.16 Nenad Corbic + * Added support for Asterisk 1.4 + * Updated support for Callweaver + * + * v1.15 Nenad Corbic + * Added PRI_CAUSE and Q931-Cause-Code + * in woomera protocol. + * + * v1.14 Nenad Corbic + * Updated for session support + * + * v1.13 Nenad Corbic + * Added CallWeaver Support + * |->(thanks to Andre Schwaller) + * Updated codec negotiation for + * mutliple profiles. + * + * v1.12 Nenad Corbic + * Updated DTMF locking + * + * v1.11 Nenad Corbic + * Updated multiple profiles + * Updated Dialect for OPAL Woomera + * Added call logging/debugging + * + * v1.10 Nenad Corbic + * Bug fix in incoming hangup + * + * v1.9 Nenad Corbic + * Fixed remote asterisk/woomera + * setup. + * + * v1.8 Nenad Corbic + * Added Woomera OPAL dialect. + * Code cleanup. + * Added cli call_status + * + * v1.7 Nenad Corbic + * Added smgdebug to enable smg debugging + * Added rdnis + * + * v1.6 Nenad Corbic + * Added incoming trunk group context + * The trunk number will be added to the + * profile context name. + * Added presentation feature. + * + * v1.5 Nenad Corbic + * Use only ALAW and MLAW not SLIN. + * This reduces the load quite a bit. + * Autodetect Format from HELLO Message. + * RxTx Gain supported in woomera.conf as well + * from CLI. + diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Makefile.svn-base b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Makefile.svn-base index 1545d06..3ac561c 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Makefile.svn-base +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Makefile.svn-base @@ -19,6 +19,8 @@ ifneq (,$(wildcard ./.pbxdir)) endif endif +CHAN_NAME=WOOMERA + $(shell echo $(PBXDIR) > .pbxdir) PBXMODDIR=/usr/lib/asterisk/modules @@ -43,11 +45,11 @@ CC = gcc INCLUDES= -I/usr/include -I./ -CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 +CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm -PBXFLAGS= $(INCLUDES) -I$(PBXDIR) -I$(PBXDIR)/include -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3 -Iinclude -I../include -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 -fomit-frame-pointer -fPIC +PBXFLAGS= $(INCLUDES) -I$(PBXDIR) -I$(PBXDIR)/include -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3 -Iinclude -I../include -D_REENTRANT -DWOOMERA_CHAN_NAME=\"$(CHAN_NAME)\" -D_GNU_SOURCE -O6 -fomit-frame-pointer -fPIC all: chan_woomera.so @@ -65,7 +67,13 @@ distclean: clean @echo OK install: all + @if [ ! -d $(INSTALLPREFIX)$(PBXMODDIR) ]; then \ + mkdir -p $(INSTALLPREFIX)$(PBXMODDIR); \ + fi; install -D -m 755 chan_woomera.so $(INSTALLPREFIX)$(PBXMODDIR)/chan_woomera.so + @if [ ! -d $(INSTALLPREFIX)$(PBXCFGDIR) ]; then \ + mkdir -p $(INSTALLPREFIX)$(PBXCFGDIR); \ + fi; @if [ -f woomera.conf ] && [ ! -e $(INSTALLPREFIX)$(PBXCFGDIR)/woomera.conf ]; then \ install -D -m 755 woomera.conf $(INSTALLPREFIX)$(PBXCFGDIR)/woomera.conf; \ fi diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/README.svn-base b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/README.svn-base index bd82080..8668eae 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/README.svn-base +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/README.svn-base @@ -66,3 +66,5 @@ The second make will know that PBXDIR=/usr/src/asterisk1.4 Each time one passes PBXDIR to makefile the local ".pbxdir" file will be updated + + diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/chan_woomera.c.svn-base b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/chan_woomera.c.svn-base index 2027153..98af621 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/chan_woomera.c.svn-base +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/chan_woomera.c.svn-base @@ -1,3 +1,4 @@ + /* * Asterisk -- A telephony toolkit for Linux. * @@ -12,6 +13,32 @@ * This program is free software, distributed under the terms of * the GNU General Public License * ============================================= + * v1.21 David Yat Sin + * Dec 27 2007 + * Support for language + * + * v1.20 David Yat Sin + * Dec 20 2007 + * Support for call confirmation + * Support for default context + * + * v1.19 Nenad Corbic + * Nov 30 2007 + * Updated for latest CallWeaver + * Updated smgversion update on master socket + * restart. + * + * v1.18 Nenad Corbic + * Updated Channel-Name on outbound call + * Check queued events on ABORT + * Major Unit Testing done + * Ability to change chan name from Makefile + * + * v1.17 Nenad Corbic + * Updates for Asterisk 1.4 + * Updated the release causes + * Updated for tech_indication + * * v1.16 Nenad Corbic * Added support for Asterisk 1.4 * Updated support for Callweaver @@ -107,7 +134,7 @@ #include "asterisk/causes.h" #include "asterisk/dsp.h" -ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.16 $") +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.21 $") #else @@ -129,9 +156,25 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.16 $") #include "callweaver/dsp.h" #include "callweaver.h" -CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.16 $") +CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.21 $") // strings... + +#define ast_config opbx_config +#define AST_CONTROL_RINGING OPBX_CONTROL_RINGING +#define AST_CONTROL_BUSY OPBX_CONTROL_BUSY +#define AST_CONTROL_CONGESTION OPBX_CONTROL_CONGESTION +#define AST_CONTROL_PROCEEDING OPBX_CONTROL_PROCEEDING +#define AST_CONTROL_PROGRESS OPBX_CONTROL_PROGRESS +#define AST_CONTROL_HOLD OPBX_CONTROL_HOLD +#define AST_CONTROL_UNHOLD OPBX_CONTROL_UNHOLD +#define AST_CONTROL_VIDUPDATE OPBX_CONTROL_VIDUPDATE + +#define LOG_NOTICE OPBX_LOG_NOTICE +#define LOG_DEBUG OPBX_LOG_DEBUG +#define LOG_ERROR OPBX_LOG_ERROR +#define LOG_WARNING OPBX_LOG_WARNING + #define AST_FORMAT_SLINEAR OPBX_FORMAT_SLINEAR #define AST_FORMAT_ULAW OPBX_FORMAT_ULAW #define AST_FORMAT_ALAW OPBX_FORMAT_ALAW @@ -224,21 +267,28 @@ CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.16 $") #include "g711.h" #include -//#define MEDIA_ANSWER "MEDIA" -// THE ONE ABOVE OR THE 2 BELOW BUT NOT BOTH -#define MEDIA_ANSWER "ACCEPT" +#define USE_TECH_INDICATE 1 +#ifdef USE_TECH_INDICATE + #define MEDIA_ANSWER "MEDIA" +#else + #define MEDIA_ANSWER "ACCEPT" +#endif + #define USE_ANSWER 1 extern int option_verbose; -#define WOOMERA_VERSION "v1.16" +#define WOOMERA_VERSION "v1.21" +#ifndef WOOMERA_CHAN_NAME +#define WOOMERA_CHAN_NAME "SS7" +#endif static int tech_count = 0; static const char desc[] = "Woomera Channel Driver"; -static const char type[] = "WOOMERA"; +//static const char type[] = "WOOMERA"; static const char tdesc[] = "Woomera Channel Driver"; static char configfile[] = "woomera.conf"; static char smgversion_init=0; @@ -270,8 +320,9 @@ static struct ast_jb_conf global_jbconf; #define WOOMERA_RECORD_SEPARATOR "\r\n\r\n" #define WOOMERA_DEBUG_PREFIX "**[WOOMERA]** " #define WOOMERA_DEBUG_LINE "--------------------------------------------------------------------------------" -#define WOOMERA_HARD_TIMEOUT -1000 +#define WOOMERA_HARD_TIMEOUT -2000 #define WOOMERA_QLEN 10 +#define WOOMERA_MAX_TRUNKGROUPS 16 /* this macro is not in all versions of asterisk */ #ifdef OLDERAST @@ -339,7 +390,12 @@ typedef enum { TFLAG_INTHREAD = (1 << 11), TFLAG_TECHHANGUP = (1 << 12), TFLAG_DESTROYED = (1 << 13), - TFLAG_UP = (1 << 14) + TFLAG_UP = (1 << 14), + TFLAG_ACCEPT = (1 << 15), + TFLAG_ACCEPTED = (1 << 16), + TFLAG_ANSWER_RECEIVED = (1 << 17), + TFLAG_CONFIRM_ANSWER = (1 << 18), + TFLAG_CONFIRM_ANSWER_ENABLED = (1 << 19) } TFLAGS; static int usecnt = 0; @@ -402,6 +458,10 @@ struct woomera_profile { int call_ok; int call_end; int call_abort; + char default_context[WOOMERA_STRLEN]; + char* tg_context [WOOMERA_MAX_TRUNKGROUPS+1]; + char language[WOOMERA_STRLEN]; + char* tg_language [WOOMERA_MAX_TRUNKGROUPS+1]; }; @@ -554,8 +614,12 @@ static int tech_answer(struct ast_channel *self); static struct ast_frame *tech_read(struct ast_channel *self); static struct ast_frame *tech_exception(struct ast_channel *self); static int tech_write(struct ast_channel *self, struct ast_frame *frame); -#if 0 +#ifdef USE_TECH_INDICATE +# ifdef AST14 +static int tech_indicate(struct ast_channel *self, int condition, const void *data, size_t datalen); +# else static int tech_indicate(struct ast_channel *self, int condition); +# endif #endif static int tech_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); static int tech_send_html(struct ast_channel *self, int subclass, const char *data, int datalen); @@ -570,6 +634,7 @@ static int tech_write_video(struct ast_channel *self, struct ast_frame *frame); static int woomera_event_incoming (private_object *tech_pvt); static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg); +static void woomera_check_event (private_object *tech_pvt, int res, woomera_message *wmsg); /******************************************************************************** * Constant structure for mapping local methods to the core interface. @@ -578,7 +643,7 @@ static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg) */ static const struct ast_channel_tech technology = { - .type = type, + .type = WOOMERA_CHAN_NAME, .description = tdesc, .capabilities = (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW), .requester = tech_requester, @@ -597,7 +662,9 @@ static const struct ast_channel_tech technology = { .read = tech_read, .write = tech_write, .exception = tech_exception, - //.indicate = tech_indicate, +#ifdef USE_TECH_INDICATE + .indicate = tech_indicate, +#endif .fixup = tech_fixup, .send_html = tech_send_html, .send_text = tech_send_text, @@ -620,6 +687,7 @@ static void woomera_close_socket(int *socket) static int woomera_message_reply_ok(woomera_message *wmsg) { + if (!(wmsg->mval >= 200 && wmsg->mval <= 299)) { return -1; } @@ -949,14 +1017,14 @@ static int woomera_message_parse(int fd, woomera_message *wmsg, int timeout, cur++; wmsg->mval = atoi(buf); } else { - ast_log(LOG_WARNING, "Malformed Message!\n"); + ast_log(LOG_NOTICE, "Malformed Message!\n"); break; } } if (cur) { strncpy(wmsg->command, cur, WOOMERA_STRLEN); } else { - ast_log(LOG_WARNING, "Malformed Message!\n"); + ast_log(LOG_NOTICE, "Malformed Message!\n"); break; } } else { @@ -1110,7 +1178,6 @@ retry_activate_again: return -1; } - if((connect_woomera(&tech_pvt->command_channel, tech_pvt->profile, 0)) > -1) { if (globals.debug > 2) { ast_log(LOG_NOTICE, @@ -1302,6 +1369,9 @@ static int tech_init(private_object *tech_pvt, woomera_profile *profile, int fla self->nativeformats = tech_pvt->coding; self->writeformat = self->rawwriteformat = self->readformat = tech_pvt->coding; tech_pvt->frame.subclass = tech_pvt->coding; + ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); + ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED); + ast_clear_flag(tech_pvt, TFLAG_ANSWER_RECEIVED); if (profile->dtmf_enable) { @@ -1373,18 +1443,11 @@ static int tech_init(private_object *tech_pvt, woomera_profile *profile, int fla /* we're gonna try "wasting" a thread to do a better realtime monitoring */ err=launch_tech_thread(tech_pvt); if (err) { - ast_log(LOG_ERROR, "Error: Failed to Lauch the thread\n"); + ast_log(LOG_ERROR, "Error: Failed to lauch tech control thread\n"); ast_clear_flag(tech_pvt, TFLAG_ACTIVATE); ast_set_flag(tech_pvt, TFLAG_ABORT); return -1; } - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - if (ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - tech_pvt->profile->call_out++; - } else { - tech_pvt->profile->call_in++; - } - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); } else { if (ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { @@ -1395,12 +1458,6 @@ static int tech_init(private_object *tech_pvt, woomera_profile *profile, int fla } - ast_mutex_lock(&profile->call_count_lock); - profile->call_count++; - tech_pvt->call_count = profile->call_count; - ast_mutex_unlock(&profile->call_count_lock); - - if (globals.debug > 2) { ast_log(LOG_NOTICE, "TECH INIT tech_pvt=%p c=%p (use=%i)\n", tech_pvt,tech_pvt->owner,usecount()); @@ -1468,6 +1525,7 @@ static void tech_destroy(private_object *tech_pvt, struct ast_channel *owner) tech_pvt); } chan->tech_pvt = NULL; + tech_pvt->owner=NULL; ast_hangup(chan); } else { if (globals.debug > 2) { @@ -1483,14 +1541,6 @@ static void tech_destroy(private_object *tech_pvt, struct ast_channel *owner) tech_pvt->owner=NULL; } - if (tech_pvt->profile) { - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - tech_pvt->profile->call_count--; - if (tech_pvt->profile->call_count < 0) { - tech_pvt->profile->call_count=0; - } - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - } /* Tech profile is allowed to be null in case the call * is blocked from the call_count */ @@ -1602,6 +1652,11 @@ static void *tech_monitor_thread(void *obj) int res = 0; tech_pvt = obj; + + if (ast_test_flag(tech_pvt, TFLAG_TECHHANGUP)) { + ast_log(LOG_NOTICE, "Tech Monitor: Call stopped before thread up!\n"); + return NULL; + } memset(tcallid,0,sizeof(tcallid)); memset(&wmsg,0,sizeof(wmsg)); @@ -1612,7 +1667,14 @@ static void *tech_monitor_thread(void *obj) tech_pvt->profile->rxgain_val, tech_pvt->profile->txgain_val); } - + ast_mutex_lock(&tech_pvt->profile->call_count_lock); + if (ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { + tech_pvt->profile->call_out++; + } else { + tech_pvt->profile->call_in++; + } + tech_pvt->profile->call_count++; + ast_mutex_unlock(&tech_pvt->profile->call_count_lock); for(;;) { @@ -1628,6 +1690,7 @@ static void *tech_monitor_thread(void *obj) tech_pvt); } } + /* finish the deferred crap asterisk won't allow us to do live */ if (ast_test_flag(tech_pvt, TFLAG_ABORT)) { @@ -1642,6 +1705,20 @@ static void *tech_monitor_thread(void *obj) aborted|=1; + /* Check for queued events, looking for HANGUP messages, + so we can return proper hangup cause */ + for (;;) { + if ((res = woomera_dequeue_event(&tech_pvt->event_queue, &wmsg))) { + woomera_check_event (tech_pvt, res, &wmsg); + } else { + break; + } + } + + ast_mutex_lock(&tech_pvt->profile->call_count_lock); + tech_pvt->profile->call_count--; + ast_mutex_unlock(&tech_pvt->profile->call_count_lock); + if (tech_pvt->profile && tech_pvt->command_channel > -1) { if (globals.debug > 2) { @@ -1709,18 +1786,27 @@ static void *tech_monitor_thread(void *obj) //ast_set_flag(tech_pvt, TFLAG_DESTROY); if (ast_test_flag(tech_pvt, TFLAG_PBX)) { + //ast_log(LOG_NOTICE,"Waiting for PBX to hangup!\n"); while (!ast_test_flag(tech_pvt, TFLAG_DESTROY)) { timeout_cnt++; - if (timeout_cnt > 4000) { //10sec timeout + if (timeout_cnt > 10000) { //10sec timeout + struct ast_channel *owner = tech_get_owner(tech_pvt); + if (owner) { + owner->tech_pvt=NULL; + } /* Five second timeout */ - ast_log(LOG_ERROR, "ERROR: Wait on destroy timedout! %s tech_pvt=%p\n", - tech_pvt->callid, tech_pvt); + ast_log(LOG_ERROR, "ERROR: Wait on destroy timedout! %s tech_pvt=%p Dir=%s\n", + tech_pvt->callid, tech_pvt, + ast_test_flag(tech_pvt, TFLAG_OUTBOUND)?"OUT":"IN" ); + + ast_set_flag(tech_pvt, TFLAG_DESTROY); break; } usleep(5000); sched_yield(); } + //ast_log(LOG_NOTICE,"Got PBX hangup!\n"); ast_mutex_lock(&tech_pvt->profile->call_count_lock); tech_pvt->profile->call_end++; ast_mutex_unlock(&tech_pvt->profile->call_count_lock); @@ -1839,6 +1925,8 @@ static void *tech_monitor_thread(void *obj) ast_set_flag(tech_pvt, TFLAG_ABORT); ast_log(LOG_NOTICE, "MEDIA ANSWER ABORT Ch=%d\n", tech_pvt->command_channel); + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; goto tech_thread_continue; } @@ -1858,6 +1946,38 @@ static void *tech_monitor_thread(void *obj) } } + if (ast_test_flag(tech_pvt, TFLAG_ACCEPT) && + ast_test_flag(tech_pvt, TFLAG_INCOMING)) { + + ast_set_flag(tech_pvt,TFLAG_ACCEPTED); + ast_clear_flag(tech_pvt,TFLAG_ACCEPT); + + woomera_printf(tech_pvt->profile, tech_pvt->command_channel, + "ACCEPT %s%s" + "Raw-Audio: %s:%d%s" + "Request-Audio: Raw%s" + "Unique-Call-Id: %s%s", + tech_pvt->callid, + WOOMERA_LINE_SEPARATOR, + tech_pvt->profile->audio_ip, + tech_pvt->port, + WOOMERA_LINE_SEPARATOR, + WOOMERA_LINE_SEPARATOR, + tech_pvt->callid, + WOOMERA_RECORD_SEPARATOR); + + if(woomera_message_parse_wait(tech_pvt,&wmsg) < 0) { + ast_set_flag(tech_pvt, TFLAG_ABORT); + ast_log(LOG_NOTICE, "ACCEPT ABORT Ch=%d\n", + tech_pvt->command_channel); + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; + goto tech_thread_continue; + continue; + } + + } + if (ast_test_flag(tech_pvt, TFLAG_ANSWER)) { @@ -1884,6 +2004,8 @@ static void *tech_monitor_thread(void *obj) ast_set_flag(tech_pvt, TFLAG_ABORT); ast_log(LOG_NOTICE, "ANSWER ABORT Ch=%d\n", tech_pvt->command_channel); + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; goto tech_thread_continue; continue; } @@ -1930,6 +2052,8 @@ static void *tech_monitor_thread(void *obj) ast_set_flag(tech_pvt, TFLAG_ABORT); ast_log(LOG_NOTICE, "DTMF ABORT Ch=%d\n", tech_pvt->command_channel); + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; goto tech_thread_continue; continue; } @@ -1948,6 +2072,8 @@ static void *tech_monitor_thread(void *obj) tech_pvt->callid,tech_pvt); } ast_set_flag(tech_pvt, TFLAG_ABORT); + ast_copy_string(tech_pvt->ds, "RECOVERY_ON_TIMER_EXPIRE", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=102; } } @@ -1966,6 +2092,8 @@ static void *tech_monitor_thread(void *obj) ast_log(LOG_NOTICE, "No Command Channel %s tpvt=%p\n", tech_pvt->callid,tech_pvt); } + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; ast_set_flag(tech_pvt, TFLAG_ABORT); goto tech_thread_continue; continue; @@ -1980,136 +2108,11 @@ static void *tech_monitor_thread(void *obj) NULL ))) { - if (globals.debug > 2) { - - if (!strcasecmp(wmsg.command, "INCOMING") ) { - /* Do not print it here */ - }else{ - ast_log(LOG_NOTICE, "WOOMERA EVENT %s : callid=%s tech_callid=%s tpvt=%p\n", - wmsg.command,wmsg.callid,tech_pvt->callid,tech_pvt); - } + woomera_check_event (tech_pvt, res, &wmsg); + if (ast_test_flag(tech_pvt, TFLAG_ABORT)) { + continue; } - - if (res < 0) { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "INVALID MESSAGE PARSE COMMAND %s tpvt=%p\n", - tech_pvt->callid,tech_pvt); - } - ast_set_flag(tech_pvt, TFLAG_ABORT); - goto tech_thread_continue; - continue; - } else if (ast_test_flag(tech_pvt, TFLAG_ABORT)) { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "GOT ABORT WHILE WAITING FOR EVENT %s tpvt=%p\n", - tech_pvt->callid,tech_pvt); - } - goto tech_thread_continue; - continue; - - } else if (!strcasecmp(wmsg.command, "HANGUP")) { - char *cause; - char *q931cause; - struct ast_channel *owner; - - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "Hangup [%s]\n", tech_pvt->callid); - } - cause = woomera_message_header(&wmsg, "Cause"); - q931cause = woomera_message_header(&wmsg, "Q931-Cause-Code"); - - owner = tech_get_owner(tech_pvt); - if (cause && owner) { - owner->hangupcause = string_to_release(cause); - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "EVENT HANGUP with OWNER with Cause %s %s tpvt=%p\n", - cause,tech_pvt->callid,tech_pvt); - } - }else{ - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "EVENT HANGUP with Cause %s %s tpvt=%p\n", - cause,tech_pvt->callid,tech_pvt); - } - } - - if (q931cause && atoi(q931cause) && owner) { - owner->hangupcause = atoi(q931cause); - } - - woomera_close_socket(&tech_pvt->command_channel); - - ast_set_flag(tech_pvt, TFLAG_ABORT); - goto tech_thread_continue; - continue; - - } else if (!strcasecmp(wmsg.command, "DTMF")) { - struct ast_frame dtmf_frame = {AST_FRAME_DTMF}; - int x = 0; - for (x = 0; x < strlen(wmsg.command_args); x++) { - struct ast_channel *owner = tech_get_owner(tech_pvt); - dtmf_frame.subclass = wmsg.command_args[x]; - - if (owner) { - ast_queue_frame(owner, ast_frdup(&dtmf_frame)); - } - - if (globals.debug > 1 && option_verbose > 1) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "SEND DTMF [%c] to %s\n", dtmf_frame.subclass,tech_pvt->callid); - } - } - } - - } else if (!strcasecmp(wmsg.command, "PROCEED")) { - /* This packet has lots of info so well keep it */ - tech_pvt->call_info = wmsg; - - - } else if (ast_test_flag(tech_pvt, TFLAG_PARSE_INCOMING) && - !strcasecmp(wmsg.command, "INCOMING")) { - - /* The INCOMING EVENT should never come here becuase - * there should be only a single LISTEN via main thread */ - - ast_log(LOG_ERROR, "INVALID WOOMERA EVENT %s :" - "callid=%s tech_callid=%s tpvt=%p\n", - wmsg.command,wmsg.callid, - tech_pvt->callid,tech_pvt); - - } else if (!strcasecmp(wmsg.command, "CONNECT")) { - struct ast_frame answer_frame = {AST_FRAME_CONTROL, AST_CONTROL_ANSWER}; - struct ast_channel *owner = tech_get_owner(tech_pvt); - - if (owner) { - ast_setstate(owner, AST_STATE_UP); - ast_queue_frame(owner, &answer_frame); - ast_set_flag(tech_pvt, TFLAG_UP); - - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - tech_pvt->profile->call_ok++; - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - - }else{ - ast_set_flag(tech_pvt, TFLAG_ABORT); - } - - - } else if (!strcasecmp(wmsg.command, "MEDIA")) { - - int err; - err=woomera_event_media (tech_pvt, &wmsg); - if (err != 0) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - } - - } else { - if (!strcasecmp(wmsg.command, "INCOMING") ) { - /* Do not print it here */ - }else{ - ast_log(LOG_ERROR, "Woomera Invalid CMD %s %s\n", - wmsg.command,tech_pvt->callid); - } - } } if (globals.debug > 4) { if (option_verbose > 2) { @@ -2165,9 +2168,12 @@ static int woomera_locate_socket(woomera_profile *profile, int *woomera_socket) if (globals.panic > 2) { break; } - ast_log(LOG_WARNING, + ast_log(LOG_NOTICE, "Woomera {%s} Cannot Reconnect! retry in 5 seconds...\n", profile->name); + + /* When we establish connection update smg version */ + smgversion_init=0; sleep(5); } @@ -2319,8 +2325,8 @@ static void *woomera_thread_run(void *obj) struct ast_channel *inchan; char *name = "Woomera"; - if (!(name = woomera_message_header(&wmsg, "Remote-Address"))) { - name = woomera_message_header(&wmsg, "Channel-Name"); + if (!(name = woomera_message_header(&wmsg, "Channel-Name"))) { + name = woomera_message_header(&wmsg,"Remote-Address"); } if (!name) { @@ -2335,7 +2341,7 @@ static void *woomera_thread_run(void *obj) ast_log(LOG_NOTICE, "NEW INBOUND CALL %s!\n",wmsg.callid); } - if ((inchan = woomera_new(type, profile->coding, name, &cause, profile))) { + if ((inchan = woomera_new(WOOMERA_CHAN_NAME, profile->coding, name, &cause, profile))) { private_object *tech_pvt; char *callid; tech_pvt = inchan->tech_pvt; @@ -2419,6 +2425,12 @@ static int launch_tech_thread(private_object *tech_pvt) } } + if (ast_test_flag(tech_pvt, TFLAG_TECHHANGUP)) { + /* Sanity check should never happen */ + ast_log(LOG_NOTICE,"Tech Thread failed call already hangup!\n"); + return -1; + } + result = pthread_attr_init(&attr); pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); @@ -2426,7 +2438,8 @@ static int launch_tech_thread(private_object *tech_pvt) result = ast_pthread_create(&tech_pvt->thread, &attr, tech_monitor_thread, tech_pvt); if (result) { ast_clear_flag(tech_pvt, TFLAG_INTHREAD); - ast_log(LOG_ERROR, "Error: Failed to launch tech thread \n"); + ast_log(LOG_ERROR, "Error: Failed to launch tech thread %s\n", + strerror(errno)); } pthread_attr_destroy(&attr); @@ -2489,7 +2502,16 @@ woomera_config_gain_skip: static void destroy_woomera_profile(woomera_profile *profile) { + int i; if (profile && ast_test_flag(profile, PFLAG_DYNAMIC)) { + for ( i = 0; i <= WOOMERA_MAX_TRUNKGROUPS; i++){ + if(profile->tg_context[i] != NULL){ + free(profile->tg_context[i]); + } + if(profile->tg_language[i] != NULL){ + free(profile->tg_language[i]); + } + } ast_mutex_destroy(&profile->iolock); ast_mutex_destroy(&profile->call_count_lock); ast_mutex_destroy(&profile->event_queue.lock); @@ -2522,6 +2544,7 @@ static int config_woomera(void) char *entry; struct ast_variable *v; woomera_profile *profile; + int default_context_set = 0; int count = 0; memset(&default_profile, 0, sizeof(default_profile)); @@ -2598,7 +2621,35 @@ static int config_woomera(void) ast_clear_flag(profile, PFLAG_OUTBOUND); } } else if (!strcmp(v->name, "context")) { + if(!default_context_set){ + default_context_set=1; + strncpy(profile->default_context, v->value, sizeof(profile->default_context) - 1); + } strncpy(profile->context, v->value, sizeof(profile->context) - 1); + } else if (!strcmp(v->name, "default_context")) { + default_context_set=1; + strncpy(profile->default_context, v->value, sizeof(profile->default_context) - 1); + } else if (!strcmp(v->name, "group")) { + int group_num = atoi(v->value); + if (group_num < 0) { + ast_log(LOG_ERROR, "Invalid group:%d (less than zero) - ignoring\n", group_num); + } else if (group_num > WOOMERA_MAX_TRUNKGROUPS){ + ast_log(LOG_ERROR, "Invalid trunkgroup:%d (exceeds max:%d) -ignoring\n", group_num, WOOMERA_MAX_TRUNKGROUPS); + } else { + if(profile->tg_context[group_num] != NULL){ + free(profile->tg_context[group_num]); + } + profile->tg_context[group_num] = strdup(profile->context); + + if(profile->tg_language[group_num] != NULL){ + free(profile->tg_language[group_num]); + } + if(strlen(profile->language)){ + profile->tg_language[group_num] = strdup(profile->language); + } + } + } else if (!strcmp(v->name, "language")) { + strncpy(profile->language, v->value, sizeof(profile->language) - 1); } else if (!strcmp(v->name, "dtmf_enable")) { profile->dtmf_enable = atoi(v->value); } else if (!strcmp(v->name, "jb_enable")) { @@ -2615,13 +2666,13 @@ static int config_woomera(void) } } else if (!strcmp(v->name, "rxgain") && profile->coding) { if (sscanf(v->value, "%f", &gain) != 1) { - ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value); + ast_log(LOG_NOTICE, "Invalid rxgain: %s\n", v->value); } else { woomera_config_gain(profile,gain,1); } } else if (!strcmp(v->name, "txgain") && profile->coding) { if (sscanf(v->value, "%f", &gain) != 1) { - ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value); + ast_log(LOG_NOTICE, "Invalid txgain: %s\n", v->value); } else { woomera_config_gain(profile,gain,0); } @@ -2721,13 +2772,16 @@ static int create_udp_socket(char *ip, int port, struct sockaddr_in *sockaddr, i static int connect_woomera(int *new_socket, woomera_profile *profile, int flags) { struct sockaddr_in localAddr, remoteAddr; - struct hostent *hp; - struct ast_hostent ahp; - int res = 0; + struct hostent *hp, *result; + struct hostent ahp; + int res = 0, err=0; + hp=&ahp; + char buf[512]; *new_socket=-1; - if ((hp = ast_gethostbyname(profile->woomera_host, &ahp))) { + gethostbyname_r(profile->woomera_host, hp, buf, sizeof(buf), &result, &err); + if (result) { remoteAddr.sin_family = hp->h_addrtype; memcpy((char *) &remoteAddr.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); remoteAddr.sin_port = htons(profile->woomera_port); @@ -2786,7 +2840,7 @@ static int connect_woomera(int *new_socket, woomera_profile *profile, int flags) if ((res = woomera_message_parse(*new_socket, &wmsg, - WOOMERA_HARD_TIMEOUT, + -10000, //WOOMERA_HARD_TIMEOUT, profile, NULL )) < 0) { @@ -2882,7 +2936,7 @@ static struct ast_channel *woomera_new(const char *type, int format, struct ast_channel *chan = NULL; char name[100]; - snprintf(name, sizeof(name), "%s/%s-%04x", "WOOMERA", (char *)data, rand() & 0xffff); + snprintf(name, sizeof(name), "%s/%s-%04x", type, (char *)data, rand() & 0xffff); if (!(tech_pvt = malloc(sizeof(private_object)))) { ast_log(LOG_ERROR, "Memory Error!\n"); @@ -2927,7 +2981,7 @@ static struct ast_channel *woomera_new(const char *type, int format, chan->nativeformats = tech_pvt->coding; chan->writeformat = chan->rawwriteformat = chan->readformat = tech_pvt->coding; tech_pvt->frame.subclass = tech_pvt->coding; - + tech_pvt->pri_cause=AST_CAUSE_NORMAL_CLEARING; ASTOBJ_CONTAINER_LINK(&private_object_list, tech_pvt); @@ -3038,6 +3092,8 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) { private_object *tech_pvt = self->tech_pvt; char *workspace; + char *p; + char *c; self->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; @@ -3051,6 +3107,9 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) self->cid.cid_pres, dest); } + + + if (self->cid.cid_name) { strncpy(tech_pvt->cid_name, self->cid.cid_name, sizeof(tech_pvt->cid_name)-1); } @@ -3068,6 +3127,7 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) char *addr, *profile_name, *proto=NULL; woomera_profile *profile; int err; + #if 0 int isprofile = 0; @@ -3125,18 +3185,18 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) } if (profile->max_calls) { - ast_mutex_lock(&profile->call_count_lock); if (profile->call_count >= profile->max_calls) { - ast_mutex_unlock(&profile->call_count_lock); if (globals.debug > 1 && option_verbose > 1) { ast_log(LOG_ERROR, "This profile is at call limit of %d\n", profile->max_calls); } goto tech_call_failed; } - ast_mutex_unlock(&profile->call_count_lock); } + + + snprintf(tech_pvt->dest, sizeof(tech_pvt->dest), "%s", addr ? addr : ""); snprintf(tech_pvt->proto, sizeof(tech_pvt->proto), "%s", proto ? proto : ""); @@ -3154,6 +3214,16 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) goto tech_call_failed; } +#if 1 + if ((p = strrchr(self->name, '/'))) { + c = p-1; + if(*c == 'c' || *c== 'C'){ + ast_set_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED); + ast_set_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); + } + } +#endif + woomera_send_progress(tech_pvt); } self->hangupcause = AST_CAUSE_NORMAL_CLEARING; @@ -3196,6 +3266,7 @@ static int tech_hangup(struct ast_channel *self) ast_mutex_lock(&tech_pvt->iolock); ast_set_flag(tech_pvt, TFLAG_TECHHANGUP); tech_pvt->owner=NULL; + self->tech_pvt=NULL; ast_mutex_unlock(&tech_pvt->iolock); @@ -3239,16 +3310,20 @@ static int tech_hangup(struct ast_channel *self) tech_pvt); } } else { + if (globals.debug > 2) { + ast_log(LOG_ERROR, "TECH HANGUP: Destroying tech not in thread! Callid=%s tech_pvt=%p Dir=%s\n", + tech_pvt->callid, tech_pvt, + ast_test_flag(tech_pvt, TFLAG_OUTBOUND)?"OUT":"IN" ); + } + if (!ast_test_flag(tech_pvt, TFLAG_DESTROY)) { tech_destroy(tech_pvt,NULL); if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH HANGUP NOT IN THREAD! tpvt=%p\n", - tech_pvt); + ast_log(LOG_NOTICE, "TECH HANGUP NOT IN THREAD!\n"); } }else{ if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH HANGUP NOT IN THREAD ALREDAY HUNGUP! tpvt=%p\n", - tech_pvt); + ast_log(LOG_NOTICE, "TECH HANGUP NOT IN THREAD ALREDAY HUNGUP! \n"); } } } @@ -3288,7 +3363,7 @@ static int tech_answer(struct ast_channel *self) ast_set_flag(tech_pvt, TFLAG_UP); ast_setstate(self, AST_STATE_UP); - + return res; } @@ -3333,7 +3408,7 @@ static int woomera_tx2ast_frm(private_object *tech_pvt, char * buf, int len ) /* 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); + ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context); } else ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten); } else @@ -3425,15 +3500,47 @@ tech_read_again: if (tech_pvt->owner && (tech_pvt->faxdetect || tech_pvt->ast_dsp)) { f = ast_dsp_process(tech_pvt->owner, tech_pvt->dsp, &tech_pvt->frame); if (f && f->frametype == AST_FRAME_DTMF){ - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "%s: Detected inband DTMF digit: %c\n", - self->name, - f->subclass); + int answer = 0; + if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED)){ + ast_mutex_lock(&tech_pvt->iolock); + if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER)){ + ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); + if(ast_test_flag(tech_pvt, TFLAG_ANSWER_RECEIVED)){ + answer = 1; + } + } + ast_mutex_unlock(&tech_pvt->iolock); + if(answer){ + struct ast_frame answer_frame = {AST_FRAME_CONTROL, AST_CONTROL_ANSWER}; + struct ast_channel *owner = tech_get_owner(tech_pvt); + ast_log(LOG_DEBUG, "Confirm answer on %s!\n", self->name); + + if (owner) { + ast_setstate(owner, AST_STATE_UP); + ast_queue_frame(owner, &answer_frame); + ast_set_flag(tech_pvt, TFLAG_UP); + + ast_mutex_lock(&tech_pvt->profile->call_count_lock); + tech_pvt->profile->call_ok++; + ast_mutex_unlock(&tech_pvt->profile->call_count_lock); + } else { + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; + ast_set_flag(tech_pvt, TFLAG_ABORT); + + } + } + } + if (answer == 0 && globals.debug > 2) { + ast_log(LOG_NOTICE, "%s: Detected inband DTMF digit: %c\n", + self->name, + f->subclass); } } + //woomera_tx2ast_frm(tech_pvt, tech_pvt->frame.data, tech_pvt->frame.datalen); - } + } if (globals.debug > 4) { @@ -3459,7 +3566,7 @@ static int tech_write(struct ast_channel *self, struct ast_frame *frame) int res = 0, i = 0; if (!tech_pvt || globals.panic || ast_test_flag(tech_pvt, TFLAG_ABORT)) { - return -1; + return 0; } if(ast_test_flag(tech_pvt, TFLAG_MEDIA) && frame->datalen) { @@ -3475,7 +3582,7 @@ static int tech_write(struct ast_channel *self, struct ast_frame *frame) i = sendto(tech_pvt->udp_socket, frame->data, frame->datalen, 0, (struct sockaddr *) &tech_pvt->udpwrite, sizeof(tech_pvt->udpwrite)); if (i < 0) { - return -1; + return i; } if (globals.debug > 4) { if (option_verbose > 4) { @@ -3485,7 +3592,7 @@ static int tech_write(struct ast_channel *self, struct ast_frame *frame) } else { - ast_log(LOG_WARNING, "Invalid frame type %d sent\n", frame->frametype); + ast_log(LOG_NOTICE, "Invalid frame type %d sent\n", frame->frametype); } } @@ -3518,17 +3625,99 @@ static struct ast_frame *tech_exception(struct ast_channel *self) } /*--- tech_indicate: Indicaate a condition to my channel ---*/ -#if 0 +#ifdef USE_TECH_INDICATE +#ifdef AST14 +static int tech_indicate(struct ast_channel *self, int condition, const void *data, size_t datalen) +#else static int tech_indicate(struct ast_channel *self, int condition) +#endif { private_object *tech_pvt; - int res = 0; + int res = -1; - tech_pvt = self->tech_pvt; if (globals.debug > 1) { ast_verbose(WOOMERA_DEBUG_PREFIX "+++INDICATE %s %d\n",self->name, condition); } + tech_pvt = self->tech_pvt; + if (!tech_pvt) { + return res; + } + + switch(condition) { + case AST_CONTROL_RINGING: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Ringing\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case AST_CONTROL_BUSY: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Busy\n"); + } + ast_copy_string(tech_pvt->ds, "BUSY", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=17; + ast_set_flag(tech_pvt, TFLAG_ABORT); + break; + case AST_CONTROL_CONGESTION: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Congestion\n"); + } + ast_copy_string(tech_pvt->ds, "BUSY", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=17; + ast_set_flag(tech_pvt, TFLAG_ABORT); + break; + case AST_CONTROL_PROCEEDING: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Proceeding\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case AST_CONTROL_PROGRESS: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Progress\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case AST_CONTROL_HOLD: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Hold\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case AST_CONTROL_UNHOLD: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: UnHold\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case AST_CONTROL_VIDUPDATE: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Vidupdate\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case -1: + res = -1; + break; + default: + ast_log(LOG_NOTICE, "Don't know how to indicate condition %d\n", condition); + res = -1; + break; + } + return res; } #endif @@ -3768,7 +3957,19 @@ static int woomera_cli(int fd, int argc, char *argv[]) return 0; } +#ifdef CALLWEAVER +static struct opbx_clicmd cli_woomera[] = { + { + .cmda = { "woomera", "default", "version", NULL }, + .handler = woomera_cli, + .summary = "Woomera Verison", + //.usage = pri_debug_help, + //.generator = complete_span_4, + }, +}; +#else static struct ast_cli_entry cli_woomera = { { "woomera", NULL }, woomera_cli, "Woomera", "Woomera" }; +#endif /******************************* CORE INTERFACE ******************************************** * These are module-specific interface functions that are common to every module @@ -3838,6 +4039,8 @@ static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg) raw_audio_header = woomera_message_header(wmsg, "Raw-Audio"); if (raw_audio_header == NULL) { + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; return 1; } @@ -3869,6 +4072,8 @@ static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg) /* Sanity Check */ owner = tech_get_owner(tech_pvt); if (!owner) { + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; return -1; } @@ -3901,22 +4106,40 @@ static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg) owner = tech_get_owner(tech_pvt); if (!owner) { + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; return -1; } if (ast_test_flag(tech_pvt, TFLAG_INBOUND)) { - if (ast_pbx_start(owner)) { - ast_log(LOG_ERROR, "Unable to start PBX on %s \n", + int pbx_res; +#ifdef AST14 + ast_mutex_lock(&owner->lock); + ast_setstate(owner, AST_STATE_RINGING); +#endif + pbx_res=ast_pbx_start(owner); +#ifdef AST14 + ast_mutex_unlock(&owner->lock); +#endif + + if (pbx_res) { + ast_log(LOG_NOTICE, "Failed to start PBX on %s \n", tech_pvt->callid); ast_set_flag(tech_pvt, TFLAG_ABORT); ast_clear_flag(tech_pvt, TFLAG_PBX); + owner->tech_pvt = NULL; + ast_copy_string(tech_pvt->ds, "SWITCH_CONGESTION", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=42; //ast_hangup(); /* Let destroy hangup */ return -1; } else { +#ifndef AST14 ast_setstate(owner, AST_STATE_RINGING); +#endif ast_set_flag(tech_pvt, TFLAG_PBX); owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; + woomera_send_progress(tech_pvt); return 0; } @@ -3930,6 +4153,8 @@ static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg) if (globals.debug) { ast_log(LOG_ERROR, "{%s} Cannot resolve %s\n", tech_pvt->profile->name, ip); } + ast_copy_string(tech_pvt->ds, "NO_ROUTE_DESTINATION", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=3; return -1; } @@ -3963,7 +4188,7 @@ static int woomera_event_incoming (private_object *tech_pvt) ast_log(LOG_NOTICE, "No Context Found %s tpvt=%p\n", tech_pvt->callid,tech_pvt); } - ast_log(LOG_WARNING, "No context configured for inbound calls aborting call!\n"); + ast_log(LOG_NOTICE, "No context configured for inbound calls aborting call!\n"); ast_set_flag(tech_pvt, TFLAG_ABORT); return -1; } @@ -4001,12 +4226,25 @@ static int woomera_event_incoming (private_object *tech_pvt) owner = tech_get_owner(tech_pvt); if (owner) { - - snprintf(owner->context, sizeof(owner->context) - 1, - "%s%s", - tech_pvt->profile->context, - tg_string); - + int group = atoi(tg_string); + if(group >= 0 && + group <= WOOMERA_MAX_TRUNKGROUPS && + tech_pvt->profile->tg_context[group] != NULL){ + + strncpy(owner->context, tech_pvt->profile->tg_context[group], sizeof(owner->context) - 1); + + if(tech_pvt->profile->tg_language[group] != NULL && + strlen(tech_pvt->profile->tg_language[group])){ + strncpy(owner->language, tech_pvt->profile->tg_language[group], sizeof(owner->language) - 1); + } + + }else { + snprintf(owner->context, sizeof(owner->context) - 1, + "%s%s", + tech_pvt->profile->default_context, + tg_string); + } + strncpy(owner->exten, exten, sizeof(owner->exten) - 1); ast_set_callerid(owner, cid_num, cid_name, cid_num); owner->cid.cid_pres=presentation; @@ -4037,21 +4275,193 @@ static int woomera_event_incoming (private_object *tech_pvt) if (validext == 0) { - - if (globals.debug > 1){ - ast_log(LOG_ERROR, "Error: Invalid exten %s@%s%s called %s!\n", - exten, - tech_pvt->profile->context, - tg_string, - tech_pvt->callid); + if (globals.debug > 1){ + int group = atoi(tg_string); + if(group >= 0 && + group <= WOOMERA_MAX_TRUNKGROUPS && + tech_pvt->profile->tg_context[group] != NULL){ + + ast_log(LOG_ERROR, "Error: Invalid exten %s@%s called %s!\n", + exten, + owner->context, + tech_pvt->callid); + }else{ + ast_log(LOG_ERROR, "Error: Invalid exten %s@%s%s called %s!\n", + exten, + tech_pvt->profile->context, + tg_string, + tech_pvt->callid); + } } - return -1; } return 0; } +static void woomera_check_event (private_object *tech_pvt, int res, woomera_message *wmsg) +{ + + if (globals.debug > 2) { + + if (!strcasecmp(wmsg->command, "INCOMING") ) { + /* Do not print it here */ + }else{ + ast_log(LOG_NOTICE, "WOOMERA EVENT %s : callid=%s tech_callid=%s tpvt=%p\n", + wmsg->command,wmsg->callid,tech_pvt->callid,tech_pvt); + } + } + + if (res < 0) { + if (globals.debug > 2) { + ast_log(LOG_NOTICE, "INVALID MESSAGE PARSE COMMAND %s tpvt=%p\n", + tech_pvt->callid,tech_pvt); + } + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; + ast_set_flag(tech_pvt, TFLAG_ABORT); + + } else if (!strcasecmp(wmsg->command, "HANGUP")) { + char *cause; + char *q931cause; + struct ast_channel *owner; + + + if (option_verbose > 2) { + ast_verbose(WOOMERA_DEBUG_PREFIX "Hangup [%s]\n", tech_pvt->callid); + } + cause = woomera_message_header(wmsg, "Cause"); + q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + owner = tech_get_owner(tech_pvt); + if (cause && owner) { + owner->hangupcause = string_to_release(cause); + if (globals.debug > 2) { + ast_log(LOG_NOTICE, "EVENT HANGUP with OWNER with Cause %s %s tpvt=%p\n", + cause,tech_pvt->callid,tech_pvt); + } + }else{ + if (globals.debug > 2) { + ast_log(LOG_NOTICE, "EVENT HANGUP with Cause %s %s tpvt=%p\n", + cause,tech_pvt->callid,tech_pvt); + } + } + + if (q931cause && atoi(q931cause) && owner) { + owner->hangupcause = atoi(q931cause); + } + + woomera_close_socket(&tech_pvt->command_channel); + + ast_set_flag(tech_pvt, TFLAG_ABORT); + + } else if (ast_test_flag(tech_pvt, TFLAG_ABORT)) { + + /* If we are in abort we only care about HANGUP + so we can get the return code */ + return; + + } else if (!strcasecmp(wmsg->command, "DTMF")) { + struct ast_frame dtmf_frame = {AST_FRAME_DTMF}; + int x = 0; + for (x = 0; x < strlen(wmsg->command_args); x++) { + struct ast_channel *owner = tech_get_owner(tech_pvt); + dtmf_frame.subclass = wmsg->command_args[x]; + + if (owner) { + ast_queue_frame(owner, ast_frdup(&dtmf_frame)); + } + + if (globals.debug > 1 && option_verbose > 1) { + if (option_verbose > 2) { + ast_verbose(WOOMERA_DEBUG_PREFIX "SEND DTMF [%c] to %s\n", dtmf_frame.subclass,tech_pvt->callid); + } + } + } + + } else if (!strcasecmp(wmsg->command, "PROCEED")) { + /* This packet has lots of info so well keep it */ + char *chan_name = woomera_message_header(wmsg, "Channel-Name"); + if (chan_name && ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { + struct ast_channel *owner = tech_get_owner(tech_pvt); + + if (owner) { +#ifdef AST14 + char newname[100]; + snprintf(newname, 100, "%s/%s", WOOMERA_CHAN_NAME, chan_name); + ast_change_name(owner,newname); +#else + snprintf(owner->name, 100, "%s/%s", WOOMERA_CHAN_NAME, chan_name); +#endif + } + } + memcpy(&tech_pvt->call_info,wmsg,sizeof(*wmsg)); + + + } else if (ast_test_flag(tech_pvt, TFLAG_PARSE_INCOMING) && + !strcasecmp(wmsg->command, "INCOMING")) { + + /* The INCOMING EVENT should never come here becuase + * there should be only a single LISTEN via main thread */ + + ast_log(LOG_ERROR, "INVALID WOOMERA EVENT %s :" + "callid=%s tech_callid=%s tpvt=%p\n", + wmsg->command,wmsg->callid, + tech_pvt->callid,tech_pvt); + + } else if (!strcasecmp(wmsg->command, "CONNECT")) { + struct ast_frame answer_frame = {AST_FRAME_CONTROL, AST_CONTROL_ANSWER}; + struct ast_channel *owner = tech_get_owner(tech_pvt); + + if (owner) { + int answer = 0; + if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED)){ + ast_mutex_lock(&tech_pvt->iolock); + ast_set_flag(tech_pvt, TFLAG_ANSWER_RECEIVED); + if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER)){ + ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %s!\n", woomera_message_header(wmsg, "Channel-Name")); + } else { + answer = 1; + } + ast_mutex_unlock(&tech_pvt->iolock); + } else { + answer = 1; + } + if(answer){ + ast_setstate(owner, AST_STATE_UP); + ast_queue_frame(owner, &answer_frame); + ast_set_flag(tech_pvt, TFLAG_UP); + + ast_mutex_lock(&tech_pvt->profile->call_count_lock); + tech_pvt->profile->call_ok++; + ast_mutex_unlock(&tech_pvt->profile->call_count_lock); + } + }else{ + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; + ast_set_flag(tech_pvt, TFLAG_ABORT); + } + + + } else if (!strcasecmp(wmsg->command, "MEDIA")) { + + int err; + err=woomera_event_media (tech_pvt, wmsg); + if (err != 0) { + ast_set_flag(tech_pvt, TFLAG_ABORT); + } + + } else { + if (!strcasecmp(wmsg->command, "INCOMING") ) { + /* Do not print it here */ + }else{ + ast_log(LOG_ERROR, "Woomera Invalid CMD %s %s\n", + wmsg->command,tech_pvt->callid); + } + } + return; +} + /*============================================================================== Module Load Section @@ -4062,7 +4472,7 @@ int load_module(void) int x; if (ast_channel_register(&technology)) { - ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); + ast_log(LOG_ERROR, "Unable to register channel class %s\n", WOOMERA_CHAN_NAME); return -1; } memset(&globals, 0, sizeof(globals)); @@ -4092,11 +4502,15 @@ int load_module(void) /* sched = sched_context_create(); if (!sched) { - ast_log(LOG_WARNING, "Unable to create schedule context\n"); + ast_log(LOG_NOTICE, "Unable to create schedule context\n"); } */ +#ifdef CALLWEAVER + opbx_cli_register_multiple(cli_woomera, arraysize(cli_woomera)); +#else ast_cli_register(&cli_woomera); +#endif return 0; } @@ -4128,7 +4542,7 @@ int unload_module(void) while (!woomera_profile_thread_running(profile, 0, 0)) { time(&now); if (now - then > 30) { - ast_log(LOG_WARNING, "Timed out waiting for thread to exit\n"); + ast_log(LOG_NOTICE, "Timed out waiting for thread to exit\n"); break; } usleep(100); @@ -4146,7 +4560,11 @@ int unload_module(void) ast_mutex_destroy(&tech_pvt_idx_lock[x]); } +#ifdef CALLWEAVER + opbx_cli_unregister_multiple(cli_woomera, sizeof(cli_woomera) / sizeof(cli_woomera[0])); +#else ast_cli_unregister(&cli_woomera); +#endif ASTOBJ_CONTAINER_DESTROY(&private_object_list); ASTOBJ_CONTAINER_DESTROYALL(&woomera_profile_list, destroy_woomera_profile); //sched_context_destroy(sched); @@ -4155,7 +4573,14 @@ int unload_module(void) return 0; } -#ifndef AST14 +#ifdef CALLWEAVER + +MODULE_INFO(load_module, reload, unload_module, NULL, desc); + +#else + + +# ifndef AST14 char *key() { @@ -4168,12 +4593,16 @@ char *description() return (char *) desc; } -#else +# else + + AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Woomera Protocol (WOOMERA)", .load = load_module, .unload = unload_module, .reload = reload, ); +# endif + #endif -; + diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/Changelog.chan_woomera b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/Changelog.chan_woomera new file mode 100644 index 0000000..8c43ac5 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/Changelog.chan_woomera @@ -0,0 +1,85 @@ +chan_woomera.c +====================================== + +Dec 27 2007 + * v1.21 David Yat Sin + * Support for language + +Dec 20 2007 + * v1.20 David Yat Sin + * Support for call confirmation + * Support for default context + +Nov 30 2007 + * v1.19 Nenad Corbic + * Updated for latest CallWeaver + * Updated smgversion update on master socket + * restart. + +Nov 22 2007 + + * v1.18 Nenad Corbic + * Updated Channel-Name on outbound call + * Check queued events on ABORT + * Major Unit Testing done + * Ability to change chan name from Makefile + * + * v1.17 Nenad Corbic + * Updates for Asterisk 1.4 + * Updated the release causes + * Updated for tech_indication + * + * v1.16 Nenad Corbic + * Added support for Asterisk 1.4 + * Updated support for Callweaver + * + * v1.15 Nenad Corbic + * Added PRI_CAUSE and Q931-Cause-Code + * in woomera protocol. + * + * v1.14 Nenad Corbic + * Updated for session support + * + * v1.13 Nenad Corbic + * Added CallWeaver Support + * |->(thanks to Andre Schwaller) + * Updated codec negotiation for + * mutliple profiles. + * + * v1.12 Nenad Corbic + * Updated DTMF locking + * + * v1.11 Nenad Corbic + * Updated multiple profiles + * Updated Dialect for OPAL Woomera + * Added call logging/debugging + * + * v1.10 Nenad Corbic + * Bug fix in incoming hangup + * + * v1.9 Nenad Corbic + * Fixed remote asterisk/woomera + * setup. + * + * v1.8 Nenad Corbic + * Added Woomera OPAL dialect. + * Code cleanup. + * Added cli call_status + * + * v1.7 Nenad Corbic + * Added smgdebug to enable smg debugging + * Added rdnis + * + * v1.6 Nenad Corbic + * Added incoming trunk group context + * The trunk number will be added to the + * profile context name. + * Added presentation feature. + * + * v1.5 Nenad Corbic + * Use only ALAW and MLAW not SLIN. + * This reduces the load quite a bit. + * Autodetect Format from HELLO Message. + * RxTx Gain supported in woomera.conf as well + * from CLI. + diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/Makefile b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/Makefile index 1545d06..3ac561c 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/Makefile +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/Makefile @@ -19,6 +19,8 @@ ifneq (,$(wildcard ./.pbxdir)) endif endif +CHAN_NAME=WOOMERA + $(shell echo $(PBXDIR) > .pbxdir) PBXMODDIR=/usr/lib/asterisk/modules @@ -43,11 +45,11 @@ CC = gcc INCLUDES= -I/usr/include -I./ -CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 +CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm -PBXFLAGS= $(INCLUDES) -I$(PBXDIR) -I$(PBXDIR)/include -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3 -Iinclude -I../include -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 -fomit-frame-pointer -fPIC +PBXFLAGS= $(INCLUDES) -I$(PBXDIR) -I$(PBXDIR)/include -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3 -Iinclude -I../include -D_REENTRANT -DWOOMERA_CHAN_NAME=\"$(CHAN_NAME)\" -D_GNU_SOURCE -O6 -fomit-frame-pointer -fPIC all: chan_woomera.so @@ -65,7 +67,13 @@ distclean: clean @echo OK install: all + @if [ ! -d $(INSTALLPREFIX)$(PBXMODDIR) ]; then \ + mkdir -p $(INSTALLPREFIX)$(PBXMODDIR); \ + fi; install -D -m 755 chan_woomera.so $(INSTALLPREFIX)$(PBXMODDIR)/chan_woomera.so + @if [ ! -d $(INSTALLPREFIX)$(PBXCFGDIR) ]; then \ + mkdir -p $(INSTALLPREFIX)$(PBXCFGDIR); \ + fi; @if [ -f woomera.conf ] && [ ! -e $(INSTALLPREFIX)$(PBXCFGDIR)/woomera.conf ]; then \ install -D -m 755 woomera.conf $(INSTALLPREFIX)$(PBXCFGDIR)/woomera.conf; \ fi diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/README b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/README index bd82080..8668eae 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/README +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/README @@ -66,3 +66,5 @@ The second make will know that PBXDIR=/usr/src/asterisk1.4 Each time one passes PBXDIR to makefile the local ".pbxdir" file will be updated + + diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/chan_woomera.c b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/chan_woomera.c index 2027153..98af621 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/chan_woomera.c +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/chan_woomera.c @@ -1,3 +1,4 @@ + /* * Asterisk -- A telephony toolkit for Linux. * @@ -12,6 +13,32 @@ * This program is free software, distributed under the terms of * the GNU General Public License * ============================================= + * v1.21 David Yat Sin + * Dec 27 2007 + * Support for language + * + * v1.20 David Yat Sin + * Dec 20 2007 + * Support for call confirmation + * Support for default context + * + * v1.19 Nenad Corbic + * Nov 30 2007 + * Updated for latest CallWeaver + * Updated smgversion update on master socket + * restart. + * + * v1.18 Nenad Corbic + * Updated Channel-Name on outbound call + * Check queued events on ABORT + * Major Unit Testing done + * Ability to change chan name from Makefile + * + * v1.17 Nenad Corbic + * Updates for Asterisk 1.4 + * Updated the release causes + * Updated for tech_indication + * * v1.16 Nenad Corbic * Added support for Asterisk 1.4 * Updated support for Callweaver @@ -107,7 +134,7 @@ #include "asterisk/causes.h" #include "asterisk/dsp.h" -ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.16 $") +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.21 $") #else @@ -129,9 +156,25 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.16 $") #include "callweaver/dsp.h" #include "callweaver.h" -CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.16 $") +CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.21 $") // strings... + +#define ast_config opbx_config +#define AST_CONTROL_RINGING OPBX_CONTROL_RINGING +#define AST_CONTROL_BUSY OPBX_CONTROL_BUSY +#define AST_CONTROL_CONGESTION OPBX_CONTROL_CONGESTION +#define AST_CONTROL_PROCEEDING OPBX_CONTROL_PROCEEDING +#define AST_CONTROL_PROGRESS OPBX_CONTROL_PROGRESS +#define AST_CONTROL_HOLD OPBX_CONTROL_HOLD +#define AST_CONTROL_UNHOLD OPBX_CONTROL_UNHOLD +#define AST_CONTROL_VIDUPDATE OPBX_CONTROL_VIDUPDATE + +#define LOG_NOTICE OPBX_LOG_NOTICE +#define LOG_DEBUG OPBX_LOG_DEBUG +#define LOG_ERROR OPBX_LOG_ERROR +#define LOG_WARNING OPBX_LOG_WARNING + #define AST_FORMAT_SLINEAR OPBX_FORMAT_SLINEAR #define AST_FORMAT_ULAW OPBX_FORMAT_ULAW #define AST_FORMAT_ALAW OPBX_FORMAT_ALAW @@ -224,21 +267,28 @@ CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.16 $") #include "g711.h" #include -//#define MEDIA_ANSWER "MEDIA" -// THE ONE ABOVE OR THE 2 BELOW BUT NOT BOTH -#define MEDIA_ANSWER "ACCEPT" +#define USE_TECH_INDICATE 1 +#ifdef USE_TECH_INDICATE + #define MEDIA_ANSWER "MEDIA" +#else + #define MEDIA_ANSWER "ACCEPT" +#endif + #define USE_ANSWER 1 extern int option_verbose; -#define WOOMERA_VERSION "v1.16" +#define WOOMERA_VERSION "v1.21" +#ifndef WOOMERA_CHAN_NAME +#define WOOMERA_CHAN_NAME "SS7" +#endif static int tech_count = 0; static const char desc[] = "Woomera Channel Driver"; -static const char type[] = "WOOMERA"; +//static const char type[] = "WOOMERA"; static const char tdesc[] = "Woomera Channel Driver"; static char configfile[] = "woomera.conf"; static char smgversion_init=0; @@ -270,8 +320,9 @@ static struct ast_jb_conf global_jbconf; #define WOOMERA_RECORD_SEPARATOR "\r\n\r\n" #define WOOMERA_DEBUG_PREFIX "**[WOOMERA]** " #define WOOMERA_DEBUG_LINE "--------------------------------------------------------------------------------" -#define WOOMERA_HARD_TIMEOUT -1000 +#define WOOMERA_HARD_TIMEOUT -2000 #define WOOMERA_QLEN 10 +#define WOOMERA_MAX_TRUNKGROUPS 16 /* this macro is not in all versions of asterisk */ #ifdef OLDERAST @@ -339,7 +390,12 @@ typedef enum { TFLAG_INTHREAD = (1 << 11), TFLAG_TECHHANGUP = (1 << 12), TFLAG_DESTROYED = (1 << 13), - TFLAG_UP = (1 << 14) + TFLAG_UP = (1 << 14), + TFLAG_ACCEPT = (1 << 15), + TFLAG_ACCEPTED = (1 << 16), + TFLAG_ANSWER_RECEIVED = (1 << 17), + TFLAG_CONFIRM_ANSWER = (1 << 18), + TFLAG_CONFIRM_ANSWER_ENABLED = (1 << 19) } TFLAGS; static int usecnt = 0; @@ -402,6 +458,10 @@ struct woomera_profile { int call_ok; int call_end; int call_abort; + char default_context[WOOMERA_STRLEN]; + char* tg_context [WOOMERA_MAX_TRUNKGROUPS+1]; + char language[WOOMERA_STRLEN]; + char* tg_language [WOOMERA_MAX_TRUNKGROUPS+1]; }; @@ -554,8 +614,12 @@ static int tech_answer(struct ast_channel *self); static struct ast_frame *tech_read(struct ast_channel *self); static struct ast_frame *tech_exception(struct ast_channel *self); static int tech_write(struct ast_channel *self, struct ast_frame *frame); -#if 0 +#ifdef USE_TECH_INDICATE +# ifdef AST14 +static int tech_indicate(struct ast_channel *self, int condition, const void *data, size_t datalen); +# else static int tech_indicate(struct ast_channel *self, int condition); +# endif #endif static int tech_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); static int tech_send_html(struct ast_channel *self, int subclass, const char *data, int datalen); @@ -570,6 +634,7 @@ static int tech_write_video(struct ast_channel *self, struct ast_frame *frame); static int woomera_event_incoming (private_object *tech_pvt); static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg); +static void woomera_check_event (private_object *tech_pvt, int res, woomera_message *wmsg); /******************************************************************************** * Constant structure for mapping local methods to the core interface. @@ -578,7 +643,7 @@ static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg) */ static const struct ast_channel_tech technology = { - .type = type, + .type = WOOMERA_CHAN_NAME, .description = tdesc, .capabilities = (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW), .requester = tech_requester, @@ -597,7 +662,9 @@ static const struct ast_channel_tech technology = { .read = tech_read, .write = tech_write, .exception = tech_exception, - //.indicate = tech_indicate, +#ifdef USE_TECH_INDICATE + .indicate = tech_indicate, +#endif .fixup = tech_fixup, .send_html = tech_send_html, .send_text = tech_send_text, @@ -620,6 +687,7 @@ static void woomera_close_socket(int *socket) static int woomera_message_reply_ok(woomera_message *wmsg) { + if (!(wmsg->mval >= 200 && wmsg->mval <= 299)) { return -1; } @@ -949,14 +1017,14 @@ static int woomera_message_parse(int fd, woomera_message *wmsg, int timeout, cur++; wmsg->mval = atoi(buf); } else { - ast_log(LOG_WARNING, "Malformed Message!\n"); + ast_log(LOG_NOTICE, "Malformed Message!\n"); break; } } if (cur) { strncpy(wmsg->command, cur, WOOMERA_STRLEN); } else { - ast_log(LOG_WARNING, "Malformed Message!\n"); + ast_log(LOG_NOTICE, "Malformed Message!\n"); break; } } else { @@ -1110,7 +1178,6 @@ retry_activate_again: return -1; } - if((connect_woomera(&tech_pvt->command_channel, tech_pvt->profile, 0)) > -1) { if (globals.debug > 2) { ast_log(LOG_NOTICE, @@ -1302,6 +1369,9 @@ static int tech_init(private_object *tech_pvt, woomera_profile *profile, int fla self->nativeformats = tech_pvt->coding; self->writeformat = self->rawwriteformat = self->readformat = tech_pvt->coding; tech_pvt->frame.subclass = tech_pvt->coding; + ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); + ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED); + ast_clear_flag(tech_pvt, TFLAG_ANSWER_RECEIVED); if (profile->dtmf_enable) { @@ -1373,18 +1443,11 @@ static int tech_init(private_object *tech_pvt, woomera_profile *profile, int fla /* we're gonna try "wasting" a thread to do a better realtime monitoring */ err=launch_tech_thread(tech_pvt); if (err) { - ast_log(LOG_ERROR, "Error: Failed to Lauch the thread\n"); + ast_log(LOG_ERROR, "Error: Failed to lauch tech control thread\n"); ast_clear_flag(tech_pvt, TFLAG_ACTIVATE); ast_set_flag(tech_pvt, TFLAG_ABORT); return -1; } - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - if (ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - tech_pvt->profile->call_out++; - } else { - tech_pvt->profile->call_in++; - } - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); } else { if (ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { @@ -1395,12 +1458,6 @@ static int tech_init(private_object *tech_pvt, woomera_profile *profile, int fla } - ast_mutex_lock(&profile->call_count_lock); - profile->call_count++; - tech_pvt->call_count = profile->call_count; - ast_mutex_unlock(&profile->call_count_lock); - - if (globals.debug > 2) { ast_log(LOG_NOTICE, "TECH INIT tech_pvt=%p c=%p (use=%i)\n", tech_pvt,tech_pvt->owner,usecount()); @@ -1468,6 +1525,7 @@ static void tech_destroy(private_object *tech_pvt, struct ast_channel *owner) tech_pvt); } chan->tech_pvt = NULL; + tech_pvt->owner=NULL; ast_hangup(chan); } else { if (globals.debug > 2) { @@ -1483,14 +1541,6 @@ static void tech_destroy(private_object *tech_pvt, struct ast_channel *owner) tech_pvt->owner=NULL; } - if (tech_pvt->profile) { - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - tech_pvt->profile->call_count--; - if (tech_pvt->profile->call_count < 0) { - tech_pvt->profile->call_count=0; - } - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - } /* Tech profile is allowed to be null in case the call * is blocked from the call_count */ @@ -1602,6 +1652,11 @@ static void *tech_monitor_thread(void *obj) int res = 0; tech_pvt = obj; + + if (ast_test_flag(tech_pvt, TFLAG_TECHHANGUP)) { + ast_log(LOG_NOTICE, "Tech Monitor: Call stopped before thread up!\n"); + return NULL; + } memset(tcallid,0,sizeof(tcallid)); memset(&wmsg,0,sizeof(wmsg)); @@ -1612,7 +1667,14 @@ static void *tech_monitor_thread(void *obj) tech_pvt->profile->rxgain_val, tech_pvt->profile->txgain_val); } - + ast_mutex_lock(&tech_pvt->profile->call_count_lock); + if (ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { + tech_pvt->profile->call_out++; + } else { + tech_pvt->profile->call_in++; + } + tech_pvt->profile->call_count++; + ast_mutex_unlock(&tech_pvt->profile->call_count_lock); for(;;) { @@ -1628,6 +1690,7 @@ static void *tech_monitor_thread(void *obj) tech_pvt); } } + /* finish the deferred crap asterisk won't allow us to do live */ if (ast_test_flag(tech_pvt, TFLAG_ABORT)) { @@ -1642,6 +1705,20 @@ static void *tech_monitor_thread(void *obj) aborted|=1; + /* Check for queued events, looking for HANGUP messages, + so we can return proper hangup cause */ + for (;;) { + if ((res = woomera_dequeue_event(&tech_pvt->event_queue, &wmsg))) { + woomera_check_event (tech_pvt, res, &wmsg); + } else { + break; + } + } + + ast_mutex_lock(&tech_pvt->profile->call_count_lock); + tech_pvt->profile->call_count--; + ast_mutex_unlock(&tech_pvt->profile->call_count_lock); + if (tech_pvt->profile && tech_pvt->command_channel > -1) { if (globals.debug > 2) { @@ -1709,18 +1786,27 @@ static void *tech_monitor_thread(void *obj) //ast_set_flag(tech_pvt, TFLAG_DESTROY); if (ast_test_flag(tech_pvt, TFLAG_PBX)) { + //ast_log(LOG_NOTICE,"Waiting for PBX to hangup!\n"); while (!ast_test_flag(tech_pvt, TFLAG_DESTROY)) { timeout_cnt++; - if (timeout_cnt > 4000) { //10sec timeout + if (timeout_cnt > 10000) { //10sec timeout + struct ast_channel *owner = tech_get_owner(tech_pvt); + if (owner) { + owner->tech_pvt=NULL; + } /* Five second timeout */ - ast_log(LOG_ERROR, "ERROR: Wait on destroy timedout! %s tech_pvt=%p\n", - tech_pvt->callid, tech_pvt); + ast_log(LOG_ERROR, "ERROR: Wait on destroy timedout! %s tech_pvt=%p Dir=%s\n", + tech_pvt->callid, tech_pvt, + ast_test_flag(tech_pvt, TFLAG_OUTBOUND)?"OUT":"IN" ); + + ast_set_flag(tech_pvt, TFLAG_DESTROY); break; } usleep(5000); sched_yield(); } + //ast_log(LOG_NOTICE,"Got PBX hangup!\n"); ast_mutex_lock(&tech_pvt->profile->call_count_lock); tech_pvt->profile->call_end++; ast_mutex_unlock(&tech_pvt->profile->call_count_lock); @@ -1839,6 +1925,8 @@ static void *tech_monitor_thread(void *obj) ast_set_flag(tech_pvt, TFLAG_ABORT); ast_log(LOG_NOTICE, "MEDIA ANSWER ABORT Ch=%d\n", tech_pvt->command_channel); + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; goto tech_thread_continue; } @@ -1858,6 +1946,38 @@ static void *tech_monitor_thread(void *obj) } } + if (ast_test_flag(tech_pvt, TFLAG_ACCEPT) && + ast_test_flag(tech_pvt, TFLAG_INCOMING)) { + + ast_set_flag(tech_pvt,TFLAG_ACCEPTED); + ast_clear_flag(tech_pvt,TFLAG_ACCEPT); + + woomera_printf(tech_pvt->profile, tech_pvt->command_channel, + "ACCEPT %s%s" + "Raw-Audio: %s:%d%s" + "Request-Audio: Raw%s" + "Unique-Call-Id: %s%s", + tech_pvt->callid, + WOOMERA_LINE_SEPARATOR, + tech_pvt->profile->audio_ip, + tech_pvt->port, + WOOMERA_LINE_SEPARATOR, + WOOMERA_LINE_SEPARATOR, + tech_pvt->callid, + WOOMERA_RECORD_SEPARATOR); + + if(woomera_message_parse_wait(tech_pvt,&wmsg) < 0) { + ast_set_flag(tech_pvt, TFLAG_ABORT); + ast_log(LOG_NOTICE, "ACCEPT ABORT Ch=%d\n", + tech_pvt->command_channel); + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; + goto tech_thread_continue; + continue; + } + + } + if (ast_test_flag(tech_pvt, TFLAG_ANSWER)) { @@ -1884,6 +2004,8 @@ static void *tech_monitor_thread(void *obj) ast_set_flag(tech_pvt, TFLAG_ABORT); ast_log(LOG_NOTICE, "ANSWER ABORT Ch=%d\n", tech_pvt->command_channel); + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; goto tech_thread_continue; continue; } @@ -1930,6 +2052,8 @@ static void *tech_monitor_thread(void *obj) ast_set_flag(tech_pvt, TFLAG_ABORT); ast_log(LOG_NOTICE, "DTMF ABORT Ch=%d\n", tech_pvt->command_channel); + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; goto tech_thread_continue; continue; } @@ -1948,6 +2072,8 @@ static void *tech_monitor_thread(void *obj) tech_pvt->callid,tech_pvt); } ast_set_flag(tech_pvt, TFLAG_ABORT); + ast_copy_string(tech_pvt->ds, "RECOVERY_ON_TIMER_EXPIRE", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=102; } } @@ -1966,6 +2092,8 @@ static void *tech_monitor_thread(void *obj) ast_log(LOG_NOTICE, "No Command Channel %s tpvt=%p\n", tech_pvt->callid,tech_pvt); } + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; ast_set_flag(tech_pvt, TFLAG_ABORT); goto tech_thread_continue; continue; @@ -1980,136 +2108,11 @@ static void *tech_monitor_thread(void *obj) NULL ))) { - if (globals.debug > 2) { - - if (!strcasecmp(wmsg.command, "INCOMING") ) { - /* Do not print it here */ - }else{ - ast_log(LOG_NOTICE, "WOOMERA EVENT %s : callid=%s tech_callid=%s tpvt=%p\n", - wmsg.command,wmsg.callid,tech_pvt->callid,tech_pvt); - } + woomera_check_event (tech_pvt, res, &wmsg); + if (ast_test_flag(tech_pvt, TFLAG_ABORT)) { + continue; } - - if (res < 0) { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "INVALID MESSAGE PARSE COMMAND %s tpvt=%p\n", - tech_pvt->callid,tech_pvt); - } - ast_set_flag(tech_pvt, TFLAG_ABORT); - goto tech_thread_continue; - continue; - } else if (ast_test_flag(tech_pvt, TFLAG_ABORT)) { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "GOT ABORT WHILE WAITING FOR EVENT %s tpvt=%p\n", - tech_pvt->callid,tech_pvt); - } - goto tech_thread_continue; - continue; - - } else if (!strcasecmp(wmsg.command, "HANGUP")) { - char *cause; - char *q931cause; - struct ast_channel *owner; - - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "Hangup [%s]\n", tech_pvt->callid); - } - cause = woomera_message_header(&wmsg, "Cause"); - q931cause = woomera_message_header(&wmsg, "Q931-Cause-Code"); - - owner = tech_get_owner(tech_pvt); - if (cause && owner) { - owner->hangupcause = string_to_release(cause); - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "EVENT HANGUP with OWNER with Cause %s %s tpvt=%p\n", - cause,tech_pvt->callid,tech_pvt); - } - }else{ - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "EVENT HANGUP with Cause %s %s tpvt=%p\n", - cause,tech_pvt->callid,tech_pvt); - } - } - - if (q931cause && atoi(q931cause) && owner) { - owner->hangupcause = atoi(q931cause); - } - - woomera_close_socket(&tech_pvt->command_channel); - - ast_set_flag(tech_pvt, TFLAG_ABORT); - goto tech_thread_continue; - continue; - - } else if (!strcasecmp(wmsg.command, "DTMF")) { - struct ast_frame dtmf_frame = {AST_FRAME_DTMF}; - int x = 0; - for (x = 0; x < strlen(wmsg.command_args); x++) { - struct ast_channel *owner = tech_get_owner(tech_pvt); - dtmf_frame.subclass = wmsg.command_args[x]; - - if (owner) { - ast_queue_frame(owner, ast_frdup(&dtmf_frame)); - } - - if (globals.debug > 1 && option_verbose > 1) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "SEND DTMF [%c] to %s\n", dtmf_frame.subclass,tech_pvt->callid); - } - } - } - - } else if (!strcasecmp(wmsg.command, "PROCEED")) { - /* This packet has lots of info so well keep it */ - tech_pvt->call_info = wmsg; - - - } else if (ast_test_flag(tech_pvt, TFLAG_PARSE_INCOMING) && - !strcasecmp(wmsg.command, "INCOMING")) { - - /* The INCOMING EVENT should never come here becuase - * there should be only a single LISTEN via main thread */ - - ast_log(LOG_ERROR, "INVALID WOOMERA EVENT %s :" - "callid=%s tech_callid=%s tpvt=%p\n", - wmsg.command,wmsg.callid, - tech_pvt->callid,tech_pvt); - - } else if (!strcasecmp(wmsg.command, "CONNECT")) { - struct ast_frame answer_frame = {AST_FRAME_CONTROL, AST_CONTROL_ANSWER}; - struct ast_channel *owner = tech_get_owner(tech_pvt); - - if (owner) { - ast_setstate(owner, AST_STATE_UP); - ast_queue_frame(owner, &answer_frame); - ast_set_flag(tech_pvt, TFLAG_UP); - - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - tech_pvt->profile->call_ok++; - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - - }else{ - ast_set_flag(tech_pvt, TFLAG_ABORT); - } - - - } else if (!strcasecmp(wmsg.command, "MEDIA")) { - - int err; - err=woomera_event_media (tech_pvt, &wmsg); - if (err != 0) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - } - - } else { - if (!strcasecmp(wmsg.command, "INCOMING") ) { - /* Do not print it here */ - }else{ - ast_log(LOG_ERROR, "Woomera Invalid CMD %s %s\n", - wmsg.command,tech_pvt->callid); - } - } } if (globals.debug > 4) { if (option_verbose > 2) { @@ -2165,9 +2168,12 @@ static int woomera_locate_socket(woomera_profile *profile, int *woomera_socket) if (globals.panic > 2) { break; } - ast_log(LOG_WARNING, + ast_log(LOG_NOTICE, "Woomera {%s} Cannot Reconnect! retry in 5 seconds...\n", profile->name); + + /* When we establish connection update smg version */ + smgversion_init=0; sleep(5); } @@ -2319,8 +2325,8 @@ static void *woomera_thread_run(void *obj) struct ast_channel *inchan; char *name = "Woomera"; - if (!(name = woomera_message_header(&wmsg, "Remote-Address"))) { - name = woomera_message_header(&wmsg, "Channel-Name"); + if (!(name = woomera_message_header(&wmsg, "Channel-Name"))) { + name = woomera_message_header(&wmsg,"Remote-Address"); } if (!name) { @@ -2335,7 +2341,7 @@ static void *woomera_thread_run(void *obj) ast_log(LOG_NOTICE, "NEW INBOUND CALL %s!\n",wmsg.callid); } - if ((inchan = woomera_new(type, profile->coding, name, &cause, profile))) { + if ((inchan = woomera_new(WOOMERA_CHAN_NAME, profile->coding, name, &cause, profile))) { private_object *tech_pvt; char *callid; tech_pvt = inchan->tech_pvt; @@ -2419,6 +2425,12 @@ static int launch_tech_thread(private_object *tech_pvt) } } + if (ast_test_flag(tech_pvt, TFLAG_TECHHANGUP)) { + /* Sanity check should never happen */ + ast_log(LOG_NOTICE,"Tech Thread failed call already hangup!\n"); + return -1; + } + result = pthread_attr_init(&attr); pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); @@ -2426,7 +2438,8 @@ static int launch_tech_thread(private_object *tech_pvt) result = ast_pthread_create(&tech_pvt->thread, &attr, tech_monitor_thread, tech_pvt); if (result) { ast_clear_flag(tech_pvt, TFLAG_INTHREAD); - ast_log(LOG_ERROR, "Error: Failed to launch tech thread \n"); + ast_log(LOG_ERROR, "Error: Failed to launch tech thread %s\n", + strerror(errno)); } pthread_attr_destroy(&attr); @@ -2489,7 +2502,16 @@ woomera_config_gain_skip: static void destroy_woomera_profile(woomera_profile *profile) { + int i; if (profile && ast_test_flag(profile, PFLAG_DYNAMIC)) { + for ( i = 0; i <= WOOMERA_MAX_TRUNKGROUPS; i++){ + if(profile->tg_context[i] != NULL){ + free(profile->tg_context[i]); + } + if(profile->tg_language[i] != NULL){ + free(profile->tg_language[i]); + } + } ast_mutex_destroy(&profile->iolock); ast_mutex_destroy(&profile->call_count_lock); ast_mutex_destroy(&profile->event_queue.lock); @@ -2522,6 +2544,7 @@ static int config_woomera(void) char *entry; struct ast_variable *v; woomera_profile *profile; + int default_context_set = 0; int count = 0; memset(&default_profile, 0, sizeof(default_profile)); @@ -2598,7 +2621,35 @@ static int config_woomera(void) ast_clear_flag(profile, PFLAG_OUTBOUND); } } else if (!strcmp(v->name, "context")) { + if(!default_context_set){ + default_context_set=1; + strncpy(profile->default_context, v->value, sizeof(profile->default_context) - 1); + } strncpy(profile->context, v->value, sizeof(profile->context) - 1); + } else if (!strcmp(v->name, "default_context")) { + default_context_set=1; + strncpy(profile->default_context, v->value, sizeof(profile->default_context) - 1); + } else if (!strcmp(v->name, "group")) { + int group_num = atoi(v->value); + if (group_num < 0) { + ast_log(LOG_ERROR, "Invalid group:%d (less than zero) - ignoring\n", group_num); + } else if (group_num > WOOMERA_MAX_TRUNKGROUPS){ + ast_log(LOG_ERROR, "Invalid trunkgroup:%d (exceeds max:%d) -ignoring\n", group_num, WOOMERA_MAX_TRUNKGROUPS); + } else { + if(profile->tg_context[group_num] != NULL){ + free(profile->tg_context[group_num]); + } + profile->tg_context[group_num] = strdup(profile->context); + + if(profile->tg_language[group_num] != NULL){ + free(profile->tg_language[group_num]); + } + if(strlen(profile->language)){ + profile->tg_language[group_num] = strdup(profile->language); + } + } + } else if (!strcmp(v->name, "language")) { + strncpy(profile->language, v->value, sizeof(profile->language) - 1); } else if (!strcmp(v->name, "dtmf_enable")) { profile->dtmf_enable = atoi(v->value); } else if (!strcmp(v->name, "jb_enable")) { @@ -2615,13 +2666,13 @@ static int config_woomera(void) } } else if (!strcmp(v->name, "rxgain") && profile->coding) { if (sscanf(v->value, "%f", &gain) != 1) { - ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value); + ast_log(LOG_NOTICE, "Invalid rxgain: %s\n", v->value); } else { woomera_config_gain(profile,gain,1); } } else if (!strcmp(v->name, "txgain") && profile->coding) { if (sscanf(v->value, "%f", &gain) != 1) { - ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value); + ast_log(LOG_NOTICE, "Invalid txgain: %s\n", v->value); } else { woomera_config_gain(profile,gain,0); } @@ -2721,13 +2772,16 @@ static int create_udp_socket(char *ip, int port, struct sockaddr_in *sockaddr, i static int connect_woomera(int *new_socket, woomera_profile *profile, int flags) { struct sockaddr_in localAddr, remoteAddr; - struct hostent *hp; - struct ast_hostent ahp; - int res = 0; + struct hostent *hp, *result; + struct hostent ahp; + int res = 0, err=0; + hp=&ahp; + char buf[512]; *new_socket=-1; - if ((hp = ast_gethostbyname(profile->woomera_host, &ahp))) { + gethostbyname_r(profile->woomera_host, hp, buf, sizeof(buf), &result, &err); + if (result) { remoteAddr.sin_family = hp->h_addrtype; memcpy((char *) &remoteAddr.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); remoteAddr.sin_port = htons(profile->woomera_port); @@ -2786,7 +2840,7 @@ static int connect_woomera(int *new_socket, woomera_profile *profile, int flags) if ((res = woomera_message_parse(*new_socket, &wmsg, - WOOMERA_HARD_TIMEOUT, + -10000, //WOOMERA_HARD_TIMEOUT, profile, NULL )) < 0) { @@ -2882,7 +2936,7 @@ static struct ast_channel *woomera_new(const char *type, int format, struct ast_channel *chan = NULL; char name[100]; - snprintf(name, sizeof(name), "%s/%s-%04x", "WOOMERA", (char *)data, rand() & 0xffff); + snprintf(name, sizeof(name), "%s/%s-%04x", type, (char *)data, rand() & 0xffff); if (!(tech_pvt = malloc(sizeof(private_object)))) { ast_log(LOG_ERROR, "Memory Error!\n"); @@ -2927,7 +2981,7 @@ static struct ast_channel *woomera_new(const char *type, int format, chan->nativeformats = tech_pvt->coding; chan->writeformat = chan->rawwriteformat = chan->readformat = tech_pvt->coding; tech_pvt->frame.subclass = tech_pvt->coding; - + tech_pvt->pri_cause=AST_CAUSE_NORMAL_CLEARING; ASTOBJ_CONTAINER_LINK(&private_object_list, tech_pvt); @@ -3038,6 +3092,8 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) { private_object *tech_pvt = self->tech_pvt; char *workspace; + char *p; + char *c; self->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; @@ -3051,6 +3107,9 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) self->cid.cid_pres, dest); } + + + if (self->cid.cid_name) { strncpy(tech_pvt->cid_name, self->cid.cid_name, sizeof(tech_pvt->cid_name)-1); } @@ -3068,6 +3127,7 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) char *addr, *profile_name, *proto=NULL; woomera_profile *profile; int err; + #if 0 int isprofile = 0; @@ -3125,18 +3185,18 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) } if (profile->max_calls) { - ast_mutex_lock(&profile->call_count_lock); if (profile->call_count >= profile->max_calls) { - ast_mutex_unlock(&profile->call_count_lock); if (globals.debug > 1 && option_verbose > 1) { ast_log(LOG_ERROR, "This profile is at call limit of %d\n", profile->max_calls); } goto tech_call_failed; } - ast_mutex_unlock(&profile->call_count_lock); } + + + snprintf(tech_pvt->dest, sizeof(tech_pvt->dest), "%s", addr ? addr : ""); snprintf(tech_pvt->proto, sizeof(tech_pvt->proto), "%s", proto ? proto : ""); @@ -3154,6 +3214,16 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) goto tech_call_failed; } +#if 1 + if ((p = strrchr(self->name, '/'))) { + c = p-1; + if(*c == 'c' || *c== 'C'){ + ast_set_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED); + ast_set_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); + } + } +#endif + woomera_send_progress(tech_pvt); } self->hangupcause = AST_CAUSE_NORMAL_CLEARING; @@ -3196,6 +3266,7 @@ static int tech_hangup(struct ast_channel *self) ast_mutex_lock(&tech_pvt->iolock); ast_set_flag(tech_pvt, TFLAG_TECHHANGUP); tech_pvt->owner=NULL; + self->tech_pvt=NULL; ast_mutex_unlock(&tech_pvt->iolock); @@ -3239,16 +3310,20 @@ static int tech_hangup(struct ast_channel *self) tech_pvt); } } else { + if (globals.debug > 2) { + ast_log(LOG_ERROR, "TECH HANGUP: Destroying tech not in thread! Callid=%s tech_pvt=%p Dir=%s\n", + tech_pvt->callid, tech_pvt, + ast_test_flag(tech_pvt, TFLAG_OUTBOUND)?"OUT":"IN" ); + } + if (!ast_test_flag(tech_pvt, TFLAG_DESTROY)) { tech_destroy(tech_pvt,NULL); if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH HANGUP NOT IN THREAD! tpvt=%p\n", - tech_pvt); + ast_log(LOG_NOTICE, "TECH HANGUP NOT IN THREAD!\n"); } }else{ if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH HANGUP NOT IN THREAD ALREDAY HUNGUP! tpvt=%p\n", - tech_pvt); + ast_log(LOG_NOTICE, "TECH HANGUP NOT IN THREAD ALREDAY HUNGUP! \n"); } } } @@ -3288,7 +3363,7 @@ static int tech_answer(struct ast_channel *self) ast_set_flag(tech_pvt, TFLAG_UP); ast_setstate(self, AST_STATE_UP); - + return res; } @@ -3333,7 +3408,7 @@ static int woomera_tx2ast_frm(private_object *tech_pvt, char * buf, int len ) /* 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); + ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context); } else ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten); } else @@ -3425,15 +3500,47 @@ tech_read_again: if (tech_pvt->owner && (tech_pvt->faxdetect || tech_pvt->ast_dsp)) { f = ast_dsp_process(tech_pvt->owner, tech_pvt->dsp, &tech_pvt->frame); if (f && f->frametype == AST_FRAME_DTMF){ - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "%s: Detected inband DTMF digit: %c\n", - self->name, - f->subclass); + int answer = 0; + if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED)){ + ast_mutex_lock(&tech_pvt->iolock); + if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER)){ + ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); + if(ast_test_flag(tech_pvt, TFLAG_ANSWER_RECEIVED)){ + answer = 1; + } + } + ast_mutex_unlock(&tech_pvt->iolock); + if(answer){ + struct ast_frame answer_frame = {AST_FRAME_CONTROL, AST_CONTROL_ANSWER}; + struct ast_channel *owner = tech_get_owner(tech_pvt); + ast_log(LOG_DEBUG, "Confirm answer on %s!\n", self->name); + + if (owner) { + ast_setstate(owner, AST_STATE_UP); + ast_queue_frame(owner, &answer_frame); + ast_set_flag(tech_pvt, TFLAG_UP); + + ast_mutex_lock(&tech_pvt->profile->call_count_lock); + tech_pvt->profile->call_ok++; + ast_mutex_unlock(&tech_pvt->profile->call_count_lock); + } else { + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; + ast_set_flag(tech_pvt, TFLAG_ABORT); + + } + } + } + if (answer == 0 && globals.debug > 2) { + ast_log(LOG_NOTICE, "%s: Detected inband DTMF digit: %c\n", + self->name, + f->subclass); } } + //woomera_tx2ast_frm(tech_pvt, tech_pvt->frame.data, tech_pvt->frame.datalen); - } + } if (globals.debug > 4) { @@ -3459,7 +3566,7 @@ static int tech_write(struct ast_channel *self, struct ast_frame *frame) int res = 0, i = 0; if (!tech_pvt || globals.panic || ast_test_flag(tech_pvt, TFLAG_ABORT)) { - return -1; + return 0; } if(ast_test_flag(tech_pvt, TFLAG_MEDIA) && frame->datalen) { @@ -3475,7 +3582,7 @@ static int tech_write(struct ast_channel *self, struct ast_frame *frame) i = sendto(tech_pvt->udp_socket, frame->data, frame->datalen, 0, (struct sockaddr *) &tech_pvt->udpwrite, sizeof(tech_pvt->udpwrite)); if (i < 0) { - return -1; + return i; } if (globals.debug > 4) { if (option_verbose > 4) { @@ -3485,7 +3592,7 @@ static int tech_write(struct ast_channel *self, struct ast_frame *frame) } else { - ast_log(LOG_WARNING, "Invalid frame type %d sent\n", frame->frametype); + ast_log(LOG_NOTICE, "Invalid frame type %d sent\n", frame->frametype); } } @@ -3518,17 +3625,99 @@ static struct ast_frame *tech_exception(struct ast_channel *self) } /*--- tech_indicate: Indicaate a condition to my channel ---*/ -#if 0 +#ifdef USE_TECH_INDICATE +#ifdef AST14 +static int tech_indicate(struct ast_channel *self, int condition, const void *data, size_t datalen) +#else static int tech_indicate(struct ast_channel *self, int condition) +#endif { private_object *tech_pvt; - int res = 0; + int res = -1; - tech_pvt = self->tech_pvt; if (globals.debug > 1) { ast_verbose(WOOMERA_DEBUG_PREFIX "+++INDICATE %s %d\n",self->name, condition); } + tech_pvt = self->tech_pvt; + if (!tech_pvt) { + return res; + } + + switch(condition) { + case AST_CONTROL_RINGING: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Ringing\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case AST_CONTROL_BUSY: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Busy\n"); + } + ast_copy_string(tech_pvt->ds, "BUSY", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=17; + ast_set_flag(tech_pvt, TFLAG_ABORT); + break; + case AST_CONTROL_CONGESTION: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Congestion\n"); + } + ast_copy_string(tech_pvt->ds, "BUSY", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=17; + ast_set_flag(tech_pvt, TFLAG_ABORT); + break; + case AST_CONTROL_PROCEEDING: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Proceeding\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case AST_CONTROL_PROGRESS: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Progress\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case AST_CONTROL_HOLD: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Hold\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case AST_CONTROL_UNHOLD: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: UnHold\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case AST_CONTROL_VIDUPDATE: + if (globals.debug > 3) { + ast_log(LOG_NOTICE, "TECH INDICATE: Vidupdate\n"); + } + if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { + ast_set_flag(tech_pvt, TFLAG_ACCEPT); + } + break; + case -1: + res = -1; + break; + default: + ast_log(LOG_NOTICE, "Don't know how to indicate condition %d\n", condition); + res = -1; + break; + } + return res; } #endif @@ -3768,7 +3957,19 @@ static int woomera_cli(int fd, int argc, char *argv[]) return 0; } +#ifdef CALLWEAVER +static struct opbx_clicmd cli_woomera[] = { + { + .cmda = { "woomera", "default", "version", NULL }, + .handler = woomera_cli, + .summary = "Woomera Verison", + //.usage = pri_debug_help, + //.generator = complete_span_4, + }, +}; +#else static struct ast_cli_entry cli_woomera = { { "woomera", NULL }, woomera_cli, "Woomera", "Woomera" }; +#endif /******************************* CORE INTERFACE ******************************************** * These are module-specific interface functions that are common to every module @@ -3838,6 +4039,8 @@ static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg) raw_audio_header = woomera_message_header(wmsg, "Raw-Audio"); if (raw_audio_header == NULL) { + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; return 1; } @@ -3869,6 +4072,8 @@ static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg) /* Sanity Check */ owner = tech_get_owner(tech_pvt); if (!owner) { + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; return -1; } @@ -3901,22 +4106,40 @@ static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg) owner = tech_get_owner(tech_pvt); if (!owner) { + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; return -1; } if (ast_test_flag(tech_pvt, TFLAG_INBOUND)) { - if (ast_pbx_start(owner)) { - ast_log(LOG_ERROR, "Unable to start PBX on %s \n", + int pbx_res; +#ifdef AST14 + ast_mutex_lock(&owner->lock); + ast_setstate(owner, AST_STATE_RINGING); +#endif + pbx_res=ast_pbx_start(owner); +#ifdef AST14 + ast_mutex_unlock(&owner->lock); +#endif + + if (pbx_res) { + ast_log(LOG_NOTICE, "Failed to start PBX on %s \n", tech_pvt->callid); ast_set_flag(tech_pvt, TFLAG_ABORT); ast_clear_flag(tech_pvt, TFLAG_PBX); + owner->tech_pvt = NULL; + ast_copy_string(tech_pvt->ds, "SWITCH_CONGESTION", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=42; //ast_hangup(); /* Let destroy hangup */ return -1; } else { +#ifndef AST14 ast_setstate(owner, AST_STATE_RINGING); +#endif ast_set_flag(tech_pvt, TFLAG_PBX); owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; + woomera_send_progress(tech_pvt); return 0; } @@ -3930,6 +4153,8 @@ static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg) if (globals.debug) { ast_log(LOG_ERROR, "{%s} Cannot resolve %s\n", tech_pvt->profile->name, ip); } + ast_copy_string(tech_pvt->ds, "NO_ROUTE_DESTINATION", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=3; return -1; } @@ -3963,7 +4188,7 @@ static int woomera_event_incoming (private_object *tech_pvt) ast_log(LOG_NOTICE, "No Context Found %s tpvt=%p\n", tech_pvt->callid,tech_pvt); } - ast_log(LOG_WARNING, "No context configured for inbound calls aborting call!\n"); + ast_log(LOG_NOTICE, "No context configured for inbound calls aborting call!\n"); ast_set_flag(tech_pvt, TFLAG_ABORT); return -1; } @@ -4001,12 +4226,25 @@ static int woomera_event_incoming (private_object *tech_pvt) owner = tech_get_owner(tech_pvt); if (owner) { - - snprintf(owner->context, sizeof(owner->context) - 1, - "%s%s", - tech_pvt->profile->context, - tg_string); - + int group = atoi(tg_string); + if(group >= 0 && + group <= WOOMERA_MAX_TRUNKGROUPS && + tech_pvt->profile->tg_context[group] != NULL){ + + strncpy(owner->context, tech_pvt->profile->tg_context[group], sizeof(owner->context) - 1); + + if(tech_pvt->profile->tg_language[group] != NULL && + strlen(tech_pvt->profile->tg_language[group])){ + strncpy(owner->language, tech_pvt->profile->tg_language[group], sizeof(owner->language) - 1); + } + + }else { + snprintf(owner->context, sizeof(owner->context) - 1, + "%s%s", + tech_pvt->profile->default_context, + tg_string); + } + strncpy(owner->exten, exten, sizeof(owner->exten) - 1); ast_set_callerid(owner, cid_num, cid_name, cid_num); owner->cid.cid_pres=presentation; @@ -4037,21 +4275,193 @@ static int woomera_event_incoming (private_object *tech_pvt) if (validext == 0) { - - if (globals.debug > 1){ - ast_log(LOG_ERROR, "Error: Invalid exten %s@%s%s called %s!\n", - exten, - tech_pvt->profile->context, - tg_string, - tech_pvt->callid); + if (globals.debug > 1){ + int group = atoi(tg_string); + if(group >= 0 && + group <= WOOMERA_MAX_TRUNKGROUPS && + tech_pvt->profile->tg_context[group] != NULL){ + + ast_log(LOG_ERROR, "Error: Invalid exten %s@%s called %s!\n", + exten, + owner->context, + tech_pvt->callid); + }else{ + ast_log(LOG_ERROR, "Error: Invalid exten %s@%s%s called %s!\n", + exten, + tech_pvt->profile->context, + tg_string, + tech_pvt->callid); + } } - return -1; } return 0; } +static void woomera_check_event (private_object *tech_pvt, int res, woomera_message *wmsg) +{ + + if (globals.debug > 2) { + + if (!strcasecmp(wmsg->command, "INCOMING") ) { + /* Do not print it here */ + }else{ + ast_log(LOG_NOTICE, "WOOMERA EVENT %s : callid=%s tech_callid=%s tpvt=%p\n", + wmsg->command,wmsg->callid,tech_pvt->callid,tech_pvt); + } + } + + if (res < 0) { + if (globals.debug > 2) { + ast_log(LOG_NOTICE, "INVALID MESSAGE PARSE COMMAND %s tpvt=%p\n", + tech_pvt->callid,tech_pvt); + } + ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=111; + ast_set_flag(tech_pvt, TFLAG_ABORT); + + } else if (!strcasecmp(wmsg->command, "HANGUP")) { + char *cause; + char *q931cause; + struct ast_channel *owner; + + + if (option_verbose > 2) { + ast_verbose(WOOMERA_DEBUG_PREFIX "Hangup [%s]\n", tech_pvt->callid); + } + cause = woomera_message_header(wmsg, "Cause"); + q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + owner = tech_get_owner(tech_pvt); + if (cause && owner) { + owner->hangupcause = string_to_release(cause); + if (globals.debug > 2) { + ast_log(LOG_NOTICE, "EVENT HANGUP with OWNER with Cause %s %s tpvt=%p\n", + cause,tech_pvt->callid,tech_pvt); + } + }else{ + if (globals.debug > 2) { + ast_log(LOG_NOTICE, "EVENT HANGUP with Cause %s %s tpvt=%p\n", + cause,tech_pvt->callid,tech_pvt); + } + } + + if (q931cause && atoi(q931cause) && owner) { + owner->hangupcause = atoi(q931cause); + } + + woomera_close_socket(&tech_pvt->command_channel); + + ast_set_flag(tech_pvt, TFLAG_ABORT); + + } else if (ast_test_flag(tech_pvt, TFLAG_ABORT)) { + + /* If we are in abort we only care about HANGUP + so we can get the return code */ + return; + + } else if (!strcasecmp(wmsg->command, "DTMF")) { + struct ast_frame dtmf_frame = {AST_FRAME_DTMF}; + int x = 0; + for (x = 0; x < strlen(wmsg->command_args); x++) { + struct ast_channel *owner = tech_get_owner(tech_pvt); + dtmf_frame.subclass = wmsg->command_args[x]; + + if (owner) { + ast_queue_frame(owner, ast_frdup(&dtmf_frame)); + } + + if (globals.debug > 1 && option_verbose > 1) { + if (option_verbose > 2) { + ast_verbose(WOOMERA_DEBUG_PREFIX "SEND DTMF [%c] to %s\n", dtmf_frame.subclass,tech_pvt->callid); + } + } + } + + } else if (!strcasecmp(wmsg->command, "PROCEED")) { + /* This packet has lots of info so well keep it */ + char *chan_name = woomera_message_header(wmsg, "Channel-Name"); + if (chan_name && ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { + struct ast_channel *owner = tech_get_owner(tech_pvt); + + if (owner) { +#ifdef AST14 + char newname[100]; + snprintf(newname, 100, "%s/%s", WOOMERA_CHAN_NAME, chan_name); + ast_change_name(owner,newname); +#else + snprintf(owner->name, 100, "%s/%s", WOOMERA_CHAN_NAME, chan_name); +#endif + } + } + memcpy(&tech_pvt->call_info,wmsg,sizeof(*wmsg)); + + + } else if (ast_test_flag(tech_pvt, TFLAG_PARSE_INCOMING) && + !strcasecmp(wmsg->command, "INCOMING")) { + + /* The INCOMING EVENT should never come here becuase + * there should be only a single LISTEN via main thread */ + + ast_log(LOG_ERROR, "INVALID WOOMERA EVENT %s :" + "callid=%s tech_callid=%s tpvt=%p\n", + wmsg->command,wmsg->callid, + tech_pvt->callid,tech_pvt); + + } else if (!strcasecmp(wmsg->command, "CONNECT")) { + struct ast_frame answer_frame = {AST_FRAME_CONTROL, AST_CONTROL_ANSWER}; + struct ast_channel *owner = tech_get_owner(tech_pvt); + + if (owner) { + int answer = 0; + if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED)){ + ast_mutex_lock(&tech_pvt->iolock); + ast_set_flag(tech_pvt, TFLAG_ANSWER_RECEIVED); + if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER)){ + ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %s!\n", woomera_message_header(wmsg, "Channel-Name")); + } else { + answer = 1; + } + ast_mutex_unlock(&tech_pvt->iolock); + } else { + answer = 1; + } + if(answer){ + ast_setstate(owner, AST_STATE_UP); + ast_queue_frame(owner, &answer_frame); + ast_set_flag(tech_pvt, TFLAG_UP); + + ast_mutex_lock(&tech_pvt->profile->call_count_lock); + tech_pvt->profile->call_ok++; + ast_mutex_unlock(&tech_pvt->profile->call_count_lock); + } + }else{ + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; + ast_set_flag(tech_pvt, TFLAG_ABORT); + } + + + } else if (!strcasecmp(wmsg->command, "MEDIA")) { + + int err; + err=woomera_event_media (tech_pvt, wmsg); + if (err != 0) { + ast_set_flag(tech_pvt, TFLAG_ABORT); + } + + } else { + if (!strcasecmp(wmsg->command, "INCOMING") ) { + /* Do not print it here */ + }else{ + ast_log(LOG_ERROR, "Woomera Invalid CMD %s %s\n", + wmsg->command,tech_pvt->callid); + } + } + return; +} + /*============================================================================== Module Load Section @@ -4062,7 +4472,7 @@ int load_module(void) int x; if (ast_channel_register(&technology)) { - ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); + ast_log(LOG_ERROR, "Unable to register channel class %s\n", WOOMERA_CHAN_NAME); return -1; } memset(&globals, 0, sizeof(globals)); @@ -4092,11 +4502,15 @@ int load_module(void) /* sched = sched_context_create(); if (!sched) { - ast_log(LOG_WARNING, "Unable to create schedule context\n"); + ast_log(LOG_NOTICE, "Unable to create schedule context\n"); } */ +#ifdef CALLWEAVER + opbx_cli_register_multiple(cli_woomera, arraysize(cli_woomera)); +#else ast_cli_register(&cli_woomera); +#endif return 0; } @@ -4128,7 +4542,7 @@ int unload_module(void) while (!woomera_profile_thread_running(profile, 0, 0)) { time(&now); if (now - then > 30) { - ast_log(LOG_WARNING, "Timed out waiting for thread to exit\n"); + ast_log(LOG_NOTICE, "Timed out waiting for thread to exit\n"); break; } usleep(100); @@ -4146,7 +4560,11 @@ int unload_module(void) ast_mutex_destroy(&tech_pvt_idx_lock[x]); } +#ifdef CALLWEAVER + opbx_cli_unregister_multiple(cli_woomera, sizeof(cli_woomera) / sizeof(cli_woomera[0])); +#else ast_cli_unregister(&cli_woomera); +#endif ASTOBJ_CONTAINER_DESTROY(&private_object_list); ASTOBJ_CONTAINER_DESTROYALL(&woomera_profile_list, destroy_woomera_profile); //sched_context_destroy(sched); @@ -4155,7 +4573,14 @@ int unload_module(void) return 0; } -#ifndef AST14 +#ifdef CALLWEAVER + +MODULE_INFO(load_module, reload, unload_module, NULL, desc); + +#else + + +# ifndef AST14 char *key() { @@ -4168,12 +4593,16 @@ char *description() return (char *) desc; } -#else +# else + + AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Woomera Protocol (WOOMERA)", .load = load_module, .unload = unload_module, .reload = reload, ); +# endif + #endif -; + diff --git a/ssmg/sangoma_mgd.trunk/conf/.svn/entries b/ssmg/sangoma_mgd.trunk/conf/.svn/entries index 3d1a14f..6ed1e4b 100644 --- a/ssmg/sangoma_mgd.trunk/conf/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/conf/.svn/entries @@ -1,7 +1,7 @@ 8 dir -24 +58 https://www.sangomapbx.com:/svn/sangoma_mgd/trunk/conf https://www.sangomapbx.com:/svn/sangoma_mgd diff --git a/ssmg/sangoma_mgd.trunk/install b/ssmg/sangoma_mgd.trunk/install index 2a77325..6e48af4 100755 --- a/ssmg/sangoma_mgd.trunk/install +++ b/ssmg/sangoma_mgd.trunk/install @@ -6,6 +6,10 @@ force="false" noss7="false" rootdir="" pbxdir=/usr/src/asterisk +pbxd="asterisk" +cfgdir="/etc/asterisk" + + while [ ! -z $1 ] do @@ -17,10 +21,10 @@ do shift pbxdir=$1 if [ "$pbxdir" = "" ]; then - echo "Error: Invalid Asterisk dir: $pbxdir!"; + echo "Error: Invalid $pbxd dir: $pbxdir!"; exit 1 elif [ ! -d $pbxdir ]; then - echo "Error: Asterisk dir does not exist: $pbxdir!"; + echo "Error: $pbxd dir does not exist: $pbxdir!"; exit 1 fi @@ -45,6 +49,16 @@ do shift done +if [ -f $pbxdir/include/callweaver.h ]; then + echo "PBXD=callweaver" > /etc/wanpipe/pbxd + pbxd="callweaver" + cfgdir="/usr/local/etc/callweaver" +else + echo "PBXD=asterisk" > /etc/wanpipe/pbxd + pbxd="asterisk" + cfgdir="/etc/asterisk" +fi + if [ $noss7 != 'true' ]; then if [ ! -e /usr/local/ss7box/$ss7boost ]; then echo "Error: ss7boost not found in /usr/local/ss7box dir"; @@ -176,7 +190,7 @@ eval "make" if [ $? -ne 0 ]; then exit 1; fi -make install +make INSTALLPREFIX=$rootdir install echo "Ok." if [ -d chan_woomera.trunk ]; then @@ -201,15 +215,9 @@ if [ -d chan_woomera.trunk ]; then exit 1; fi - make install + make INSTALLPREFIX=$rootdir install echo "Ok." - if [ -d /etc/asterisk ]; then - if [ ! -f /etc/asterisk/woomera.conf ]; then - \cp -f woomera.conf /etc/asterisk - fi - fi - else echo "Warning: chan_woomera directory does not exist!" exit 1 @@ -225,8 +233,8 @@ echo "--> Start: sangoma_mgd -bg" echo echo " Chan Woomera Install Done" echo -echo "--> Config: /etc/asterisk/woomera.conf" -echo "--> Start: Part of Asterisk (start asterisk)" +echo "--> Config: $cfgdir/woomera.conf" +echo "--> Start: start $pbxd (part of $pbxd)" echo echo "---------------------------------" diff --git a/ssmg/sangoma_mgd.trunk/lib/.svn/all-wcprops b/ssmg/sangoma_mgd.trunk/lib/.svn/all-wcprops index 79884d2..2e1bd16 100644 --- a/ssmg/sangoma_mgd.trunk/lib/.svn/all-wcprops +++ b/ssmg/sangoma_mgd.trunk/lib/.svn/all-wcprops @@ -1,5 +1,5 @@ K 25 svn:wc:ra_dav:version-url V 38 -/svn/sangoma_mgd/!svn/ver/20/trunk/lib +/svn/sangoma_mgd/!svn/ver/49/trunk/lib END diff --git a/ssmg/sangoma_mgd.trunk/lib/.svn/entries b/ssmg/sangoma_mgd.trunk/lib/.svn/entries index 0ec1894..8514f2e 100644 --- a/ssmg/sangoma_mgd.trunk/lib/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/lib/.svn/entries @@ -1,14 +1,14 @@ 8 dir -24 +58 https://www.sangomapbx.com:/svn/sangoma_mgd/trunk/lib https://www.sangomapbx.com:/svn/sangoma_mgd -2007-09-25T02:04:57.936973Z -20 +2007-12-05T21:10:15.262399Z +49 ncorbic diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/.deps/.svn/entries b/ssmg/sangoma_mgd.trunk/lib/libteletone/.deps/.svn/entries index 40d4dd1..dc0815e 100644 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/.deps/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/lib/libteletone/.deps/.svn/entries @@ -1,7 +1,7 @@ 8 dir -24 +58 https://www.sangomapbx.com:/svn/sangoma_mgd/trunk/lib/libteletone/.deps https://www.sangomapbx.com:/svn/sangoma_mgd @@ -32,7 +32,7 @@ file -2007-09-21T21:00:53.000000Z +2007-12-05T19:57:28.000000Z fc88672102538198c5fcc7b0a0cfc4b9 2007-09-21T20:53:51.260136Z 1 @@ -44,7 +44,7 @@ file -2007-09-21T21:00:52.000000Z +2007-12-05T19:57:27.000000Z c763fc59d24f080c3a707e2f0454808c 2007-09-21T20:53:51.260136Z 1 diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/all-wcprops b/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/all-wcprops index 8629c25..da6439e 100644 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/all-wcprops +++ b/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/all-wcprops @@ -1,7 +1,7 @@ K 25 svn:wc:ra_dav:version-url V 50 -/svn/sangoma_mgd/!svn/ver/20/trunk/lib/libteletone +/svn/sangoma_mgd/!svn/ver/49/trunk/lib/libteletone END mkinstalldirs K 25 @@ -21,12 +21,6 @@ svn:wc:ra_dav:version-url V 61 /svn/sangoma_mgd/!svn/ver/1/trunk/lib/libteletone/Makefile.in END -config.log -K 25 -svn:wc:ra_dav:version-url -V 60 -/svn/sangoma_mgd/!svn/ver/4/trunk/lib/libteletone/config.log -END AUTHORS K 25 svn:wc:ra_dav:version-url @@ -45,12 +39,6 @@ svn:wc:ra_dav:version-url V 57 /svn/sangoma_mgd/!svn/ver/1/trunk/lib/libteletone/depcomp END -config.status -K 25 -svn:wc:ra_dav:version-url -V 63 -/svn/sangoma_mgd/!svn/ver/4/trunk/lib/libteletone/config.status -END ChangeLog K 25 svn:wc:ra_dav:version-url @@ -147,12 +135,6 @@ svn:wc:ra_dav:version-url V 60 /svn/sangoma_mgd/!svn/ver/1/trunk/lib/libteletone/aclocal.m4 END -Makefile -K 25 -svn:wc:ra_dav:version-url -V 58 -/svn/sangoma_mgd/!svn/ver/4/trunk/lib/libteletone/Makefile -END install-sh K 25 svn:wc:ra_dav:version-url diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/entries b/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/entries index 59ca504..d9ffd70 100644 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/entries @@ -1,14 +1,14 @@ 8 dir -24 +58 https://www.sangomapbx.com:/svn/sangoma_mgd/trunk/lib/libteletone https://www.sangomapbx.com:/svn/sangoma_mgd -2007-09-25T02:04:57.936973Z -20 +2007-12-05T21:10:15.262399Z +49 ncorbic @@ -63,18 +63,6 @@ file 1 root -config.log -file - - - - -2007-09-21T21:04:01.000000Z -f44c820cb27388bf0405b3e069d5c860 -2007-09-21T21:04:29.921415Z -4 -ncorbic - AUTHORS file @@ -115,19 +103,6 @@ file 1 root -config.status -file - - - - -2007-09-21T21:04:01.000000Z -b9df10c61c3eb8283374deff60d89707 -2007-09-21T21:04:29.921415Z -4 -ncorbic -has-props - ChangeLog file @@ -219,7 +194,7 @@ file -2007-09-21T21:04:00.000000Z +2007-12-31T16:38:51.000000Z abcebd272f6e68af6b81e21fb7eec687 2007-09-21T21:04:29.921415Z 4 @@ -325,18 +300,6 @@ e41e60b06c482e1de80a44404e3c4c30 1 root -Makefile -file - - - - -2007-09-21T21:04:01.000000Z -315e6550b21dac6d39646ea999a8d5d9 -2007-09-21T21:04:29.921415Z -4 -ncorbic - install-sh file diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/prop-base/config.status.svn-base b/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/prop-base/config.status.svn-base deleted file mode 100644 index a669705..0000000 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/prop-base/config.status.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 14 -svn:executable -V 0 - -END diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/text-base/Makefile.svn-base b/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/text-base/Makefile.svn-base deleted file mode 100644 index cd4df29..0000000 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/text-base/Makefile.svn-base +++ /dev/null @@ -1,739 +0,0 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. -# Makefile. Generated from Makefile.in by configure. - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - - - -srcdir = . -top_srcdir = . - -pkgdatadir = $(datadir)/libteletone -pkglibdir = $(libdir)/libteletone -pkgincludedir = $(includedir)/libteletone -top_builddir = . -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = /usr/bin/install -c -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = i686-pc-linux-gnu -host_triplet = i686-pc-linux-gnu -DIST_COMMON = README $(am__configure_deps) $(library_include_HEADERS) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ - compile config.guess config.sub depcomp install-sh ltmain.sh \ - missing mkinstalldirs -subdir = . -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno configure.status.lineno -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; -am__installdirs = "$(DESTDIR)$(libdir)" \ - "$(DESTDIR)$(library_includedir)" -libLTLIBRARIES_INSTALL = $(INSTALL) -LTLIBRARIES = $(lib_LTLIBRARIES) -libteletone_la_LIBADD = -am_libteletone_la_OBJECTS = libteletone_la-libteletone_generate.lo \ - libteletone_la-libteletone_detect.lo -libteletone_la_OBJECTS = $(am_libteletone_la_OBJECTS) -DEFAULT_INCLUDES = -I. -I$(srcdir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(libteletone_la_SOURCES) -DIST_SOURCES = $(libteletone_la_SOURCES) -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-exec-recursive install-info-recursive \ - install-recursive installcheck-recursive installdirs-recursive \ - pdf-recursive ps-recursive uninstall-info-recursive \ - uninstall-recursive -library_includeHEADERS_INSTALL = $(INSTALL_HEADER) -HEADERS = $(library_include_HEADERS) -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - { test ! -d $(distdir) \ - || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -fr $(distdir); }; } -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -distuninstallcheck_listfiles = find . -type f -print -distcleancheck_listfiles = find . -type f -print -ACLOCAL = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run aclocal-1.9 -AMDEP_FALSE = # -AMDEP_TRUE = -AMTAR = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run tar -AR = ar -AUTOCONF = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoconf -AUTOHEADER = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoheader -AUTOMAKE = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run automake-1.9 -AWK = gawk -CC = gcc -CCDEPMODE = depmode=gcc3 -CFLAGS = -g -O2 -CPP = gcc -E -CPPFLAGS = -CXX = g++ -CXXCPP = g++ -E -CXXDEPMODE = depmode=gcc3 -CXXFLAGS = -g -O2 -CYGPATH_W = echo -DEFS = -DPACKAGE_NAME=\"FULL-PACKAGE-NAME\" -DPACKAGE_TARNAME=\"full-package-name\" -DPACKAGE_VERSION=\"VERSION\" -DPACKAGE_STRING=\"FULL-PACKAGE-NAME\ VERSION\" -DPACKAGE_BUGREPORT=\"BUG-REPORT-ADDRESS\" -DPACKAGE=\"libteletone\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DHAVE_DIRENT_H=1 -DSTDC_HEADERS=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DRETSIGTYPE=void -DHAVE_STRFTIME=1 -DEPDIR = .deps -ECHO = echo -ECHO_C = -ECHO_N = -n -ECHO_T = -EGREP = grep -E -EXEEXT = -F77 = f95 -FFLAGS = -g -O2 -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s -LDFLAGS = -LIBOBJS = -LIBS = -LIBTOOL = $(SHELL) $(top_builddir)/libtool -LN_S = ln -s -LTLIBOBJS = -MAKEINFO = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run makeinfo -OBJEXT = o -PACKAGE = libteletone -PACKAGE_BUGREPORT = BUG-REPORT-ADDRESS -PACKAGE_NAME = FULL-PACKAGE-NAME -PACKAGE_STRING = FULL-PACKAGE-NAME VERSION -PACKAGE_TARNAME = full-package-name -PACKAGE_VERSION = VERSION -PATH_SEPARATOR = : -RANLIB = ranlib -SET_MAKE = -SHELL = /bin/sh -STRIP = strip -VERSION = 0.1 -ac_ct_AR = ar -ac_ct_CC = gcc -ac_ct_CXX = g++ -ac_ct_F77 = f95 -ac_ct_RANLIB = ranlib -ac_ct_STRIP = strip -am__fastdepCC_FALSE = # -am__fastdepCC_TRUE = -am__fastdepCXX_FALSE = # -am__fastdepCXX_TRUE = -am__include = include -am__leading_dot = . -am__quote = -am__tar = ${AMTAR} chof - "$$tardir" -am__untar = ${AMTAR} xf - -bindir = ${exec_prefix}/bin -build = i686-pc-linux-gnu -build_alias = -build_cpu = i686 -build_os = linux-gnu -build_vendor = pc -datadir = ${prefix}/share -exec_prefix = ${prefix} -host = i686-pc-linux-gnu -host_alias = -host_cpu = i686 -host_os = linux-gnu -host_vendor = pc -includedir = ${prefix}/include -infodir = ${prefix}/info -install_sh = /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/install-sh -libdir = ${exec_prefix}/lib -libexecdir = ${exec_prefix}/libexec -localstatedir = ${prefix}/var -mandir = ${prefix}/man -mkdir_p = mkdir -p -- -oldincludedir = /usr/include -prefix = /usr/local -program_transform_name = s,x,x, -sbindir = ${exec_prefix}/sbin -sharedstatedir = ${prefix}/com -sysconfdir = ${prefix}/etc -target_alias = -EXTRA_DIST = -SUBDIRS = -AUTOMAKE_OPTS = gnu -MAKE = make -NAME = teletone -AM_CC = gcc -AM_CFLAGS = -D_GNU_SOURCE -Wall -Werror -ansi -pedantic -g -O2 -I./src -AM_CPPFLAGS = $(AM_CFLAGS) -AM_LDFLAGS = -lm -lib_LTLIBRARIES = libteletone.la -libteletone_la_SOURCES = src/libteletone_generate.c src/libteletone_detect.c -libteletone_la_CFLAGS = $(AM_CFLAGS) -libteletone_la_LDFLAGS = -library_includedir = $(prefix)/include -library_include_HEADERS = src/libteletone.h src/libteletone_detect.h src/libteletone_generate.h -all: all-recursive - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -am--refresh: - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ - cd $(srcdir) && $(AUTOMAKE) --gnu \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - if test -f $$p; then \ - f=$(am__strip_dir) \ - echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ - else :; fi; \ - done - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - p=$(am__strip_dir) \ - echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ - $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -libteletone.la: $(libteletone_la_OBJECTS) $(libteletone_la_DEPENDENCIES) - $(LINK) -rpath $(libdir) $(libteletone_la_LDFLAGS) $(libteletone_la_OBJECTS) $(libteletone_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -include ./$(DEPDIR)/libteletone_la-libteletone_detect.Plo -include ./$(DEPDIR)/libteletone_la-libteletone_generate.Plo - -.c.o: - if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ - then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -# source='$<' object='$@' libtool=no \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(COMPILE) -c $< - -.c.obj: - if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ - then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -# source='$<' object='$@' libtool=no \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: - if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ - then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -# source='$<' object='$@' libtool=yes \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(LTCOMPILE) -c -o $@ $< - -libteletone_la-libteletone_generate.lo: src/libteletone_generate.c - if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libteletone_la_CFLAGS) $(CFLAGS) -MT libteletone_la-libteletone_generate.lo -MD -MP -MF "$(DEPDIR)/libteletone_la-libteletone_generate.Tpo" -c -o libteletone_la-libteletone_generate.lo `test -f 'src/libteletone_generate.c' || echo '$(srcdir)/'`src/libteletone_generate.c; \ - then mv -f "$(DEPDIR)/libteletone_la-libteletone_generate.Tpo" "$(DEPDIR)/libteletone_la-libteletone_generate.Plo"; else rm -f "$(DEPDIR)/libteletone_la-libteletone_generate.Tpo"; exit 1; fi -# source='src/libteletone_generate.c' object='libteletone_la-libteletone_generate.lo' libtool=yes \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libteletone_la_CFLAGS) $(CFLAGS) -c -o libteletone_la-libteletone_generate.lo `test -f 'src/libteletone_generate.c' || echo '$(srcdir)/'`src/libteletone_generate.c - -libteletone_la-libteletone_detect.lo: src/libteletone_detect.c - if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libteletone_la_CFLAGS) $(CFLAGS) -MT libteletone_la-libteletone_detect.lo -MD -MP -MF "$(DEPDIR)/libteletone_la-libteletone_detect.Tpo" -c -o libteletone_la-libteletone_detect.lo `test -f 'src/libteletone_detect.c' || echo '$(srcdir)/'`src/libteletone_detect.c; \ - then mv -f "$(DEPDIR)/libteletone_la-libteletone_detect.Tpo" "$(DEPDIR)/libteletone_la-libteletone_detect.Plo"; else rm -f "$(DEPDIR)/libteletone_la-libteletone_detect.Tpo"; exit 1; fi -# source='src/libteletone_detect.c' object='libteletone_la-libteletone_detect.lo' libtool=yes \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libteletone_la_CFLAGS) $(CFLAGS) -c -o libteletone_la-libteletone_detect.lo `test -f 'src/libteletone_detect.c' || echo '$(srcdir)/'`src/libteletone_detect.c - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: -install-library_includeHEADERS: $(library_include_HEADERS) - @$(NORMAL_INSTALL) - test -z "$(library_includedir)" || $(mkdir_p) "$(DESTDIR)$(library_includedir)" - @list='$(library_include_HEADERS)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(am__strip_dir) \ - echo " $(library_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(library_includedir)/$$f'"; \ - $(library_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(library_includedir)/$$f"; \ - done - -uninstall-library_includeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(library_include_HEADERS)'; for p in $$list; do \ - f=$(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(library_includedir)/$$f'"; \ - rm -f "$(DESTDIR)$(library_includedir)/$$f"; \ - done - -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -mostlyclean-recursive clean-recursive distclean-recursive \ -maintainer-clean-recursive: - @failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - $(am__remove_distdir) - mkdir $(distdir) - $(mkdir_p) $(distdir)/src - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done - list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(mkdir_p) "$(distdir)/$$subdir" \ - || exit 1; \ - distdir=`$(am__cd) $(distdir) && pwd`; \ - top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ - (cd $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$top_distdir" \ - distdir="$$distdir/$$subdir" \ - distdir) \ - || exit 1; \ - fi; \ - done - -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r $(distdir) -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 - $(am__remove_distdir) - -dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) - -dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) - -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst - chmod a-w $(distdir) - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && cd $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck - $(am__remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' -distuninstallcheck: - @cd $(distuninstallcheck_dir) \ - && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am -check: check-recursive -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: installdirs-recursive -installdirs-am: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(library_includedir)"; do \ - test -z "$$dir" || $(mkdir_p) "$$dir"; \ - done -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ - mostlyclean-am - -distclean: distclean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-libtool distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -info: info-recursive - -info-am: - -install-data-am: install-library_includeHEADERS - -install-exec-am: install-libLTLIBRARIES - -install-info: install-info-recursive - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES \ - uninstall-library_includeHEADERS - -uninstall-info: uninstall-info-recursive - -.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ - check-am clean clean-generic clean-libLTLIBRARIES \ - clean-libtool clean-recursive ctags ctags-recursive dist \ - dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip \ - distcheck distclean distclean-compile distclean-generic \ - distclean-libtool distclean-recursive distclean-tags \ - distcleancheck distdir distuninstallcheck dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-exec install-exec-am install-info \ - install-info-am install-libLTLIBRARIES \ - install-library_includeHEADERS install-man install-strip \ - installcheck installcheck-am installdirs installdirs-am \ - maintainer-clean maintainer-clean-generic \ - maintainer-clean-recursive mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \ - pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ - uninstall-info-am uninstall-libLTLIBRARIES \ - uninstall-library_includeHEADERS - - -dox: - cd docs && doxygen $(PWD)/docs/Doxygen.conf -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/text-base/config.log.svn-base b/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/text-base/config.log.svn-base deleted file mode 100644 index fe6897d..0000000 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/text-base/config.log.svn-base +++ /dev/null @@ -1,995 +0,0 @@ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by FULL-PACKAGE-NAME configure VERSION, which was -generated by GNU Autoconf 2.59. Invocation command line was - - $ ./configure - -## --------- ## -## Platform. ## -## --------- ## - -hostname = tesla -uname -m = i686 -uname -r = 2.6.18-8.el5 -uname -s = Linux -uname -v = #1 SMP Thu Mar 15 19:57:35 EDT 2007 - -/usr/bin/uname -p = unknown -/bin/uname -X = unknown - -/bin/arch = i686 -/usr/bin/arch -k = unknown -/usr/convex/getsysinfo = unknown -hostinfo = unknown -/bin/machine = unknown -/usr/bin/oslevel = unknown -/bin/universe = unknown - -PATH: /usr/lib/qt-3.3/bin -PATH: /usr/kerberos/sbin -PATH: /usr/kerberos/bin -PATH: /usr/local/sbin -PATH: /usr/local/bin -PATH: /sbin -PATH: /bin -PATH: /usr/sbin -PATH: /usr/bin -PATH: /usr/X11R6/bin -PATH: /usr/sbin/scripts -PATH: /root/bin -PATH: /usr/sbin/scripts - - -## ----------- ## -## Core tests. ## -## ----------- ## - -configure:1551: checking for a BSD-compatible install -configure:1606: result: /usr/bin/install -c -configure:1617: checking whether build environment is sane -configure:1660: result: yes -configure:1725: checking for gawk -configure:1741: found /bin/gawk -configure:1751: result: gawk -configure:1761: checking whether make sets $(MAKE) -configure:1781: result: yes -configure:1999: checking for gcc -configure:2015: found /usr/bin/gcc -configure:2025: result: gcc -configure:2269: checking for C compiler version -configure:2272: gcc --version &5 -gcc (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52) -Copyright (C) 2006 Free Software Foundation, Inc. -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -configure:2275: $? = 0 -configure:2277: gcc -v &5 -Using built-in specs. -Target: i386-redhat-linux -Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux -Thread model: posix -gcc version 4.1.1 20070105 (Red Hat 4.1.1-52) -configure:2280: $? = 0 -configure:2282: gcc -V &5 -gcc: '-V' option must have argument -configure:2285: $? = 1 -configure:2308: checking for C compiler default output file name -configure:2311: gcc conftest.c >&5 -configure:2314: $? = 0 -configure:2360: result: a.out -configure:2365: checking whether the C compiler works -configure:2371: ./a.out -configure:2374: $? = 0 -configure:2391: result: yes -configure:2398: checking whether we are cross compiling -configure:2400: result: no -configure:2403: checking for suffix of executables -configure:2405: gcc -o conftest conftest.c >&5 -configure:2408: $? = 0 -configure:2433: result: -configure:2439: checking for suffix of object files -configure:2460: gcc -c conftest.c >&5 -configure:2463: $? = 0 -configure:2485: result: o -configure:2489: checking whether we are using the GNU C compiler -configure:2513: gcc -c conftest.c >&5 -configure:2519: $? = 0 -configure:2523: test -z - || test ! -s conftest.err -configure:2526: $? = 0 -configure:2529: test -s conftest.o -configure:2532: $? = 0 -configure:2545: result: yes -configure:2551: checking whether gcc accepts -g -configure:2572: gcc -c -g conftest.c >&5 -configure:2578: $? = 0 -configure:2582: test -z - || test ! -s conftest.err -configure:2585: $? = 0 -configure:2588: test -s conftest.o -configure:2591: $? = 0 -configure:2602: result: yes -configure:2619: checking for gcc option to accept ANSI C -configure:2689: gcc -c -g -O2 conftest.c >&5 -configure:2695: $? = 0 -configure:2699: test -z - || test ! -s conftest.err -configure:2702: $? = 0 -configure:2705: test -s conftest.o -configure:2708: $? = 0 -configure:2726: result: none needed -configure:2744: gcc -c -g -O2 conftest.c >&5 -conftest.c:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'me' -configure:2750: $? = 1 -configure: failed program was: -| #ifndef __cplusplus -| choke me -| #endif -configure:2894: checking for style of include used by make -configure:2922: result: GNU -configure:2950: checking dependency style of gcc -configure:3040: result: gcc3 -configure:3057: checking whether make sets $(MAKE) -configure:3077: result: yes -configure:3164: checking build system type -configure:3182: result: i686-pc-linux-gnu -configure:3190: checking host system type -configure:3204: result: i686-pc-linux-gnu -configure:3212: checking for a sed that does not truncate output -configure:3266: result: /bin/sed -configure:3269: checking for egrep -configure:3279: result: grep -E -configure:3295: checking for ld used by gcc -configure:3362: result: /usr/bin/ld -configure:3371: checking if the linker (/usr/bin/ld) is GNU ld -configure:3386: result: yes -configure:3391: checking for /usr/bin/ld option to reload object files -configure:3398: result: -r -configure:3416: checking for BSD-compatible nm -configure:3458: result: /usr/bin/nm -B -configure:3462: checking whether ln -s works -configure:3466: result: yes -configure:3473: checking how to recognise dependent libraries -configure:3645: result: pass_all -configure:3859: checking how to run the C preprocessor -configure:3894: gcc -E conftest.c -configure:3900: $? = 0 -configure:3932: gcc -E conftest.c -conftest.c:11:28: error: ac_nonexistent.h: No such file or directory -configure:3938: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| -| #define PACKAGE_NAME "FULL-PACKAGE-NAME" -| #define PACKAGE_TARNAME "full-package-name" -| #define PACKAGE_VERSION "VERSION" -| #define PACKAGE_STRING "FULL-PACKAGE-NAME VERSION" -| #define PACKAGE_BUGREPORT "BUG-REPORT-ADDRESS" -| #define PACKAGE "libteletone" -| #define VERSION "0.1" -| /* end confdefs.h. */ -| #include -configure:3977: result: gcc -E -configure:4001: gcc -E conftest.c -configure:4007: $? = 0 -configure:4039: gcc -E conftest.c -conftest.c:11:28: error: ac_nonexistent.h: No such file or directory -configure:4045: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| -| #define PACKAGE_NAME "FULL-PACKAGE-NAME" -| #define PACKAGE_TARNAME "full-package-name" -| #define PACKAGE_VERSION "VERSION" -| #define PACKAGE_STRING "FULL-PACKAGE-NAME VERSION" -| #define PACKAGE_BUGREPORT "BUG-REPORT-ADDRESS" -| #define PACKAGE "libteletone" -| #define VERSION "0.1" -| /* end confdefs.h. */ -| #include -configure:4089: checking for ANSI C header files -configure:4114: gcc -c -g -O2 conftest.c >&5 -configure:4120: $? = 0 -configure:4124: test -z - || test ! -s conftest.err -configure:4127: $? = 0 -configure:4130: test -s conftest.o -configure:4133: $? = 0 -configure:4222: gcc -o conftest -g -O2 conftest.c >&5 -conftest.c: In function 'main': -conftest.c:28: warning: incompatible implicit declaration of built-in function 'exit' -configure:4225: $? = 0 -configure:4227: ./conftest -configure:4230: $? = 0 -configure:4245: result: yes -configure:4269: checking for sys/types.h -configure:4285: gcc -c -g -O2 conftest.c >&5 -configure:4291: $? = 0 -configure:4295: test -z - || test ! -s conftest.err -configure:4298: $? = 0 -configure:4301: test -s conftest.o -configure:4304: $? = 0 -configure:4315: result: yes -configure:4269: checking for sys/stat.h -configure:4285: gcc -c -g -O2 conftest.c >&5 -configure:4291: $? = 0 -configure:4295: test -z - || test ! -s conftest.err -configure:4298: $? = 0 -configure:4301: test -s conftest.o -configure:4304: $? = 0 -configure:4315: result: yes -configure:4269: checking for stdlib.h -configure:4285: gcc -c -g -O2 conftest.c >&5 -configure:4291: $? = 0 -configure:4295: test -z - || test ! -s conftest.err -configure:4298: $? = 0 -configure:4301: test -s conftest.o -configure:4304: $? = 0 -configure:4315: result: yes -configure:4269: checking for string.h -configure:4285: gcc -c -g -O2 conftest.c >&5 -configure:4291: $? = 0 -configure:4295: test -z - || test ! -s conftest.err -configure:4298: $? = 0 -configure:4301: test -s conftest.o -configure:4304: $? = 0 -configure:4315: result: yes -configure:4269: checking for memory.h -configure:4285: gcc -c -g -O2 conftest.c >&5 -configure:4291: $? = 0 -configure:4295: test -z - || test ! -s conftest.err -configure:4298: $? = 0 -configure:4301: test -s conftest.o -configure:4304: $? = 0 -configure:4315: result: yes -configure:4269: checking for strings.h -configure:4285: gcc -c -g -O2 conftest.c >&5 -configure:4291: $? = 0 -configure:4295: test -z - || test ! -s conftest.err -configure:4298: $? = 0 -configure:4301: test -s conftest.o -configure:4304: $? = 0 -configure:4315: result: yes -configure:4269: checking for inttypes.h -configure:4285: gcc -c -g -O2 conftest.c >&5 -configure:4291: $? = 0 -configure:4295: test -z - || test ! -s conftest.err -configure:4298: $? = 0 -configure:4301: test -s conftest.o -configure:4304: $? = 0 -configure:4315: result: yes -configure:4269: checking for stdint.h -configure:4285: gcc -c -g -O2 conftest.c >&5 -configure:4291: $? = 0 -configure:4295: test -z - || test ! -s conftest.err -configure:4298: $? = 0 -configure:4301: test -s conftest.o -configure:4304: $? = 0 -configure:4315: result: yes -configure:4269: checking for unistd.h -configure:4285: gcc -c -g -O2 conftest.c >&5 -configure:4291: $? = 0 -configure:4295: test -z - || test ! -s conftest.err -configure:4298: $? = 0 -configure:4301: test -s conftest.o -configure:4304: $? = 0 -configure:4315: result: yes -configure:4341: checking dlfcn.h usability -configure:4353: gcc -c -g -O2 conftest.c >&5 -configure:4359: $? = 0 -configure:4363: test -z - || test ! -s conftest.err -configure:4366: $? = 0 -configure:4369: test -s conftest.o -configure:4372: $? = 0 -configure:4382: result: yes -configure:4386: checking dlfcn.h presence -configure:4396: gcc -E conftest.c -configure:4402: $? = 0 -configure:4422: result: yes -configure:4457: checking for dlfcn.h -configure:4464: result: yes -configure:4529: checking for g++ -configure:4545: found /usr/bin/g++ -configure:4555: result: g++ -configure:4571: checking for C++ compiler version -configure:4574: g++ --version &5 -g++ (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52) -Copyright (C) 2006 Free Software Foundation, Inc. -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -configure:4577: $? = 0 -configure:4579: g++ -v &5 -Using built-in specs. -Target: i386-redhat-linux -Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux -Thread model: posix -gcc version 4.1.1 20070105 (Red Hat 4.1.1-52) -configure:4582: $? = 0 -configure:4584: g++ -V &5 -g++: '-V' option must have argument -configure:4587: $? = 1 -configure:4590: checking whether we are using the GNU C++ compiler -configure:4614: g++ -c conftest.cc >&5 -configure:4620: $? = 0 -configure:4624: test -z - || test ! -s conftest.err -configure:4627: $? = 0 -configure:4630: test -s conftest.o -configure:4633: $? = 0 -configure:4646: result: yes -configure:4652: checking whether g++ accepts -g -configure:4673: g++ -c -g conftest.cc >&5 -configure:4679: $? = 0 -configure:4683: test -z - || test ! -s conftest.err -configure:4686: $? = 0 -configure:4689: test -s conftest.o -configure:4692: $? = 0 -configure:4703: result: yes -configure:4745: g++ -c -g -O2 conftest.cc >&5 -configure:4751: $? = 0 -configure:4755: test -z - || test ! -s conftest.err -configure:4758: $? = 0 -configure:4761: test -s conftest.o -configure:4764: $? = 0 -configure:4790: g++ -c -g -O2 conftest.cc >&5 -conftest.cc: In function 'int main()': -conftest.cc:26: error: 'exit' was not declared in this scope -configure:4796: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| -| #define PACKAGE_NAME "FULL-PACKAGE-NAME" -| #define PACKAGE_TARNAME "full-package-name" -| #define PACKAGE_VERSION "VERSION" -| #define PACKAGE_STRING "FULL-PACKAGE-NAME VERSION" -| #define PACKAGE_BUGREPORT "BUG-REPORT-ADDRESS" -| #define PACKAGE "libteletone" -| #define VERSION "0.1" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| /* end confdefs.h. */ -| -| int -| main () -| { -| exit (42); -| ; -| return 0; -| } -configure:4745: g++ -c -g -O2 conftest.cc >&5 -configure:4751: $? = 0 -configure:4755: test -z - || test ! -s conftest.err -configure:4758: $? = 0 -configure:4761: test -s conftest.o -configure:4764: $? = 0 -configure:4790: g++ -c -g -O2 conftest.cc >&5 -configure:4796: $? = 0 -configure:4800: test -z - || test ! -s conftest.err -configure:4803: $? = 0 -configure:4806: test -s conftest.o -configure:4809: $? = 0 -configure:4834: checking dependency style of g++ -configure:4924: result: gcc3 -configure:4951: checking how to run the C++ preprocessor -configure:4982: g++ -E conftest.cc -configure:4988: $? = 0 -configure:5020: g++ -E conftest.cc -conftest.cc:25:28: error: ac_nonexistent.h: No such file or directory -configure:5026: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| -| #define PACKAGE_NAME "FULL-PACKAGE-NAME" -| #define PACKAGE_TARNAME "full-package-name" -| #define PACKAGE_VERSION "VERSION" -| #define PACKAGE_STRING "FULL-PACKAGE-NAME VERSION" -| #define PACKAGE_BUGREPORT "BUG-REPORT-ADDRESS" -| #define PACKAGE "libteletone" -| #define VERSION "0.1" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #ifdef __cplusplus -| extern "C" void std::exit (int) throw (); using std::exit; -| #endif -| /* end confdefs.h. */ -| #include -configure:5065: result: g++ -E -configure:5089: g++ -E conftest.cc -configure:5095: $? = 0 -configure:5127: g++ -E conftest.cc -conftest.cc:25:28: error: ac_nonexistent.h: No such file or directory -configure:5133: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| -| #define PACKAGE_NAME "FULL-PACKAGE-NAME" -| #define PACKAGE_TARNAME "full-package-name" -| #define PACKAGE_VERSION "VERSION" -| #define PACKAGE_STRING "FULL-PACKAGE-NAME VERSION" -| #define PACKAGE_BUGREPORT "BUG-REPORT-ADDRESS" -| #define PACKAGE "libteletone" -| #define VERSION "0.1" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #ifdef __cplusplus -| extern "C" void std::exit (int) throw (); using std::exit; -| #endif -| /* end confdefs.h. */ -| #include -configure:5230: checking for g77 -configure:5259: result: no -configure:5230: checking for f77 -configure:5259: result: no -configure:5230: checking for xlf -configure:5259: result: no -configure:5230: checking for frt -configure:5259: result: no -configure:5230: checking for pgf77 -configure:5259: result: no -configure:5230: checking for fort77 -configure:5259: result: no -configure:5230: checking for fl32 -configure:5259: result: no -configure:5230: checking for af77 -configure:5259: result: no -configure:5230: checking for f90 -configure:5259: result: no -configure:5230: checking for xlf90 -configure:5259: result: no -configure:5230: checking for pgf90 -configure:5259: result: no -configure:5230: checking for epcf90 -configure:5259: result: no -configure:5230: checking for f95 -configure:5246: found /usr/bin/f95 -configure:5256: result: f95 -configure:5271: checking for Fortran 77 compiler version -configure:5274: f95 --version &5 -GNU Fortran 95 (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52) -Copyright (C) 2006 Free Software Foundation, Inc. - -GNU Fortran comes with NO WARRANTY, to the extent permitted by law. -You may redistribute copies of GNU Fortran -under the terms of the GNU General Public License. -For more information about these matters, see the file named COPYING - -configure:5277: $? = 0 -configure:5279: f95 -v &5 -Using built-in specs. -Target: i386-redhat-linux -Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux -Thread model: posix -gcc version 4.1.1 20070105 (Red Hat 4.1.1-52) -configure:5282: $? = 0 -configure:5284: f95 -V &5 -f95: '-V' option must have argument -configure:5287: $? = 1 -configure:5295: checking whether we are using the GNU Fortran 77 compiler -configure:5309: f95 -c conftest.F >&5 -configure:5315: $? = 0 -configure:5319: test -z - || test ! -s conftest.err -configure:5322: $? = 0 -configure:5325: test -s conftest.o -configure:5328: $? = 0 -configure:5341: result: yes -configure:5347: checking whether f95 accepts -g -configure:5359: f95 -c -g conftest.f >&5 -configure:5365: $? = 0 -configure:5369: test -z - || test ! -s conftest.err -configure:5372: $? = 0 -configure:5375: test -s conftest.o -configure:5378: $? = 0 -configure:5390: result: yes -configure:5420: checking the maximum length of command line arguments -configure:5512: result: 32768 -configure:5523: checking command to parse /usr/bin/nm -B output from gcc object -configure:5619: gcc -c -g -O2 conftest.c >&5 -configure:5622: $? = 0 -configure:5626: /usr/bin/nm -B conftest.o \| sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' \> conftest.nm -configure:5629: $? = 0 -configure:5681: gcc -o conftest -g -O2 conftest.c conftstm.o >&5 -configure:5684: $? = 0 -configure:5722: result: ok -configure:5726: checking for objdir -configure:5741: result: .libs -configure:5831: checking for ar -configure:5847: found /usr/bin/ar -configure:5858: result: ar -configure:5911: checking for ranlib -configure:5927: found /usr/bin/ranlib -configure:5938: result: ranlib -configure:5991: checking for strip -configure:6007: found /usr/bin/strip -configure:6018: result: strip -configure:6305: checking if gcc static flag works -configure:6333: result: yes -configure:6351: checking if gcc supports -fno-rtti -fno-exceptions -configure:6369: gcc -c -g -O2 -fno-rtti -fno-exceptions conftest.c >&5 -cc1: warning: command line option "-fno-rtti" is valid for C++/ObjC++ but not for C -configure:6373: $? = 0 -configure:6386: result: no -configure:6401: checking for gcc option to produce PIC -configure:6605: result: -fPIC -configure:6613: checking if gcc PIC flag -fPIC works -configure:6631: gcc -c -g -O2 -fPIC -DPIC conftest.c >&5 -configure:6635: $? = 0 -configure:6648: result: yes -configure:6672: checking if gcc supports -c -o file.o -configure:6693: gcc -c -g -O2 -o out/conftest2.o conftest.c >&5 -configure:6697: $? = 0 -configure:6719: result: yes -configure:6745: checking whether the gcc linker (/usr/bin/ld) supports shared libraries -configure:7641: result: yes -configure:7667: checking whether -lc should be explicitly linked in -configure:7672: gcc -c -g -O2 conftest.c >&5 -configure:7675: $? = 0 -configure:7689: gcc -shared conftest.o -v -Wl,-soname -Wl,conftest -o conftest 2\>\&1 \| grep -lc \>/dev/null 2\>\&1 -configure:7692: $? = 0 -configure:7704: result: no -configure:7712: checking dynamic linker characteristics -configure:8266: result: GNU/Linux ld.so -configure:8270: checking how to hardcode library paths into programs -configure:8295: result: immediate -configure:8309: checking whether stripping libraries is possible -configure:8314: result: yes -configure:9144: checking if libtool supports shared libraries -configure:9146: result: yes -configure:9149: checking whether to build shared libraries -configure:9170: result: yes -configure:9173: checking whether to build static libraries -configure:9177: result: yes -configure:9269: creating libtool -configure:9847: checking for ld used by g++ -configure:9914: result: /usr/bin/ld -configure:9923: checking if the linker (/usr/bin/ld) is GNU ld -configure:9938: result: yes -configure:9989: checking whether the g++ linker (/usr/bin/ld) supports shared libraries -configure:10869: result: yes -configure:10887: g++ -c -g -O2 conftest.cpp >&5 -configure:10890: $? = 0 -configure:11000: checking for g++ option to produce PIC -configure:11268: result: -fPIC -configure:11276: checking if g++ PIC flag -fPIC works -configure:11294: g++ -c -g -O2 -fPIC -DPIC conftest.cpp >&5 -configure:11298: $? = 0 -configure:11311: result: yes -configure:11335: checking if g++ supports -c -o file.o -configure:11356: g++ -c -g -O2 -o out/conftest2.o conftest.cpp >&5 -configure:11360: $? = 0 -configure:11382: result: yes -configure:11408: checking whether the g++ linker (/usr/bin/ld) supports shared libraries -configure:11433: result: yes -configure:11504: checking dynamic linker characteristics -configure:12058: result: GNU/Linux ld.so -configure:12062: checking how to hardcode library paths into programs -configure:12087: result: immediate -configure:12101: checking whether stripping libraries is possible -configure:12106: result: yes -configure:13442: checking if libtool supports shared libraries -configure:13444: result: yes -configure:13447: checking whether to build shared libraries -configure:13467: result: yes -configure:13470: checking whether to build static libraries -configure:13474: result: yes -configure:13486: checking for f95 option to produce PIC -configure:13690: result: -fPIC -configure:13698: checking if f95 PIC flag -fPIC works -configure:13716: f95 -c -g -O2 -fPIC conftest.f >&5 -configure:13720: $? = 0 -configure:13733: result: yes -configure:13757: checking if f95 supports -c -o file.o -configure:13778: f95 -c -g -O2 -o out/conftest2.o conftest.f >&5 -configure:13782: $? = 0 -configure:13804: result: yes -configure:13830: checking whether the f95 linker (/usr/bin/ld) supports shared libraries -configure:14706: result: yes -configure:14777: checking dynamic linker characteristics -configure:15331: result: GNU/Linux ld.so -configure:15335: checking how to hardcode library paths into programs -configure:15360: result: immediate -configure:15374: checking whether stripping libraries is possible -configure:15379: result: yes -configure:19641: checking for a BSD-compatible install -configure:19696: result: /usr/bin/install -c -configure:19717: checking for dirent.h that defines DIR -configure:19741: gcc -c -g -O2 conftest.c >&5 -configure:19747: $? = 0 -configure:19751: test -z - || test ! -s conftest.err -configure:19754: $? = 0 -configure:19757: test -s conftest.o -configure:19760: $? = 0 -configure:19771: result: yes -configure:19784: checking for library containing opendir -configure:19814: gcc -o conftest -g -O2 conftest.c >&5 -configure:19820: $? = 0 -configure:19824: test -z - || test ! -s conftest.err -configure:19827: $? = 0 -configure:19830: test -s conftest -configure:19833: $? = 0 -configure:19903: result: none required -configure:20039: checking for ANSI C header files -configure:20195: result: yes -configure:20208: checking for an ANSI C-conforming const -configure:20275: gcc -c -g -O2 conftest.c >&5 -configure:20281: $? = 0 -configure:20285: test -z - || test ! -s conftest.err -configure:20288: $? = 0 -configure:20291: test -s conftest.o -configure:20294: $? = 0 -configure:20305: result: yes -configure:20315: checking for inline -configure:20336: gcc -c -g -O2 conftest.c >&5 -configure:20342: $? = 0 -configure:20346: test -z - || test ! -s conftest.err -configure:20349: $? = 0 -configure:20352: test -s conftest.o -configure:20355: $? = 0 -configure:20367: result: inline -configure:20386: checking for size_t -configure:20410: gcc -c -g -O2 conftest.c >&5 -configure:20416: $? = 0 -configure:20420: test -z - || test ! -s conftest.err -configure:20423: $? = 0 -configure:20426: test -s conftest.o -configure:20429: $? = 0 -configure:20440: result: yes -configure:20452: checking whether time.h and sys/time.h may both be included -configure:20477: gcc -c -g -O2 conftest.c >&5 -configure:20483: $? = 0 -configure:20487: test -z - || test ! -s conftest.err -configure:20490: $? = 0 -configure:20493: test -s conftest.o -configure:20496: $? = 0 -configure:20507: result: yes -configure:20517: checking whether struct tm is in sys/time.h or time.h -configure:20540: gcc -c -g -O2 conftest.c >&5 -configure:20546: $? = 0 -configure:20550: test -z - || test ! -s conftest.err -configure:20553: $? = 0 -configure:20556: test -s conftest.o -configure:20559: $? = 0 -configure:20570: result: time.h -configure:20583: checking whether gcc needs -traditional -configure:20625: result: no -configure:20637: checking for stdlib.h -configure:20642: result: yes -configure:20782: checking for GNU libc compatible malloc -configure:20811: gcc -o conftest -g -O2 conftest.c >&5 -configure:20814: $? = 0 -configure:20816: ./conftest -configure:20819: $? = 0 -configure:20833: result: yes -configure:20863: checking return type of signal handlers -configure:20894: gcc -c -g -O2 conftest.c >&5 -configure:20900: $? = 0 -configure:20904: test -z - || test ! -s conftest.err -configure:20907: $? = 0 -configure:20910: test -s conftest.o -configure:20913: $? = 0 -configure:20924: result: void -configure:20936: checking for strftime -configure:20993: gcc -o conftest -g -O2 conftest.c >&5 -conftest.c:55: warning: conflicting types for built-in function 'strftime' -configure:20999: $? = 0 -configure:21003: test -z - || test ! -s conftest.err -configure:21006: $? = 0 -configure:21009: test -s conftest -configure:21012: $? = 0 -configure:21024: result: yes -configure:21260: creating ./config.status - -## ---------------------- ## -## Running config.status. ## -## ---------------------- ## - -This file was extended by FULL-PACKAGE-NAME config.status VERSION, which was -generated by GNU Autoconf 2.59. Invocation command line was - - CONFIG_FILES = - CONFIG_HEADERS = - CONFIG_LINKS = - CONFIG_COMMANDS = - $ ./config.status - -on tesla - -config.status:706: creating Makefile -config.status:889: executing depfiles commands - -## ---------------- ## -## Cache variables. ## -## ---------------- ## - -ac_cv_build=i686-pc-linux-gnu -ac_cv_build_alias=i686-pc-linux-gnu -ac_cv_c_compiler_gnu=yes -ac_cv_c_const=yes -ac_cv_c_inline=inline -ac_cv_cxx_compiler_gnu=yes -ac_cv_env_CC_set= -ac_cv_env_CC_value= -ac_cv_env_CFLAGS_set= -ac_cv_env_CFLAGS_value= -ac_cv_env_CPPFLAGS_set= -ac_cv_env_CPPFLAGS_value= -ac_cv_env_CPP_set= -ac_cv_env_CPP_value= -ac_cv_env_CXXCPP_set= -ac_cv_env_CXXCPP_value= -ac_cv_env_CXXFLAGS_set= -ac_cv_env_CXXFLAGS_value= -ac_cv_env_CXX_set= -ac_cv_env_CXX_value= -ac_cv_env_F77_set= -ac_cv_env_F77_value= -ac_cv_env_FFLAGS_set= -ac_cv_env_FFLAGS_value= -ac_cv_env_LDFLAGS_set= -ac_cv_env_LDFLAGS_value= -ac_cv_env_build_alias_set= -ac_cv_env_build_alias_value= -ac_cv_env_host_alias_set= -ac_cv_env_host_alias_value= -ac_cv_env_target_alias_set= -ac_cv_env_target_alias_value= -ac_cv_exeext= -ac_cv_f77_compiler_gnu=yes -ac_cv_func_malloc_0_nonnull=yes -ac_cv_func_strftime=yes -ac_cv_header_dirent_dirent_h=yes -ac_cv_header_dlfcn_h=yes -ac_cv_header_inttypes_h=yes -ac_cv_header_memory_h=yes -ac_cv_header_stdc=yes -ac_cv_header_stdint_h=yes -ac_cv_header_stdlib_h=yes -ac_cv_header_string_h=yes -ac_cv_header_strings_h=yes -ac_cv_header_sys_stat_h=yes -ac_cv_header_sys_types_h=yes -ac_cv_header_time=yes -ac_cv_header_unistd_h=yes -ac_cv_host=i686-pc-linux-gnu -ac_cv_host_alias=i686-pc-linux-gnu -ac_cv_objext=o -ac_cv_path_install='/usr/bin/install -c' -ac_cv_prog_AWK=gawk -ac_cv_prog_CPP='gcc -E' -ac_cv_prog_CXXCPP='g++ -E' -ac_cv_prog_ac_ct_AR=ar -ac_cv_prog_ac_ct_CC=gcc -ac_cv_prog_ac_ct_CXX=g++ -ac_cv_prog_ac_ct_F77=f95 -ac_cv_prog_ac_ct_RANLIB=ranlib -ac_cv_prog_ac_ct_STRIP=strip -ac_cv_prog_cc_g=yes -ac_cv_prog_cc_stdc= -ac_cv_prog_cxx_g=yes -ac_cv_prog_egrep='grep -E' -ac_cv_prog_f77_g=yes -ac_cv_prog_gcc_traditional=no -ac_cv_prog_make_make_set=yes -ac_cv_search_opendir='none required' -ac_cv_struct_tm=time.h -ac_cv_type_signal=void -ac_cv_type_size_t=yes -am_cv_CC_dependencies_compiler_type=gcc3 -am_cv_CXX_dependencies_compiler_type=gcc3 -lt_cv_deplibs_check_method=pass_all -lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_ld_reload_flag=-r -lt_cv_objdir=.libs -lt_cv_path_LD=/usr/bin/ld -lt_cv_path_LDCXX=/usr/bin/ld -lt_cv_path_NM='/usr/bin/nm -B' -lt_cv_path_SED=/bin/sed -lt_cv_prog_compiler_c_o=yes -lt_cv_prog_compiler_c_o_CXX=yes -lt_cv_prog_compiler_c_o_F77=yes -lt_cv_prog_compiler_rtti_exceptions=no -lt_cv_prog_gnu_ld=yes -lt_cv_prog_gnu_ldcxx=yes -lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p'\''' -lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (lt_ptr) 0},/p'\'' -e '\''s/^[BCDEGRST] \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr) \&\2},/p'\''' -lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^. .* \(.*\)$/extern int \1;/p'\''' -lt_cv_sys_max_cmd_len=32768 -lt_lt_cv_prog_compiler_c_o='"yes"' -lt_lt_cv_prog_compiler_c_o_CXX='"yes"' -lt_lt_cv_prog_compiler_c_o_F77='"yes"' -lt_lt_cv_sys_global_symbol_pipe='"sed -n -e '\''s/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'\''"' -lt_lt_cv_sys_global_symbol_to_c_name_address='"sed -n -e '\''s/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p'\'' -e '\''s/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'\''"' -lt_lt_cv_sys_global_symbol_to_cdecl='"sed -n -e '\''s/^. .* \\(.*\\)\$/extern int \\1;/p'\''"' - -## ----------------- ## -## Output variables. ## -## ----------------- ## - -ACLOCAL='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run aclocal-1.9' -AMDEPBACKSLASH='\' -AMDEP_FALSE='#' -AMDEP_TRUE='' -AMTAR='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run tar' -AR='ar' -AUTOCONF='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoconf' -AUTOHEADER='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoheader' -AUTOMAKE='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run automake-1.9' -AWK='gawk' -CC='gcc' -CCDEPMODE='depmode=gcc3' -CFLAGS='-g -O2' -CPP='gcc -E' -CPPFLAGS='' -CXX='g++' -CXXCPP='g++ -E' -CXXDEPMODE='depmode=gcc3' -CXXFLAGS='-g -O2' -CYGPATH_W='echo' -DEFS='-DPACKAGE_NAME=\"FULL-PACKAGE-NAME\" -DPACKAGE_TARNAME=\"full-package-name\" -DPACKAGE_VERSION=\"VERSION\" -DPACKAGE_STRING=\"FULL-PACKAGE-NAME\ VERSION\" -DPACKAGE_BUGREPORT=\"BUG-REPORT-ADDRESS\" -DPACKAGE=\"libteletone\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DHAVE_DIRENT_H=1 -DSTDC_HEADERS=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DRETSIGTYPE=void -DHAVE_STRFTIME=1 ' -DEPDIR='.deps' -ECHO='echo' -ECHO_C='' -ECHO_N='-n' -ECHO_T='' -EGREP='grep -E' -EXEEXT='' -F77='f95' -FFLAGS='-g -O2' -INSTALL_DATA='${INSTALL} -m 644' -INSTALL_PROGRAM='${INSTALL}' -INSTALL_SCRIPT='${INSTALL}' -INSTALL_STRIP_PROGRAM='${SHELL} $(install_sh) -c -s' -LDFLAGS='' -LIBOBJS='' -LIBS='' -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -LN_S='ln -s' -LTLIBOBJS='' -MAKEINFO='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run makeinfo' -OBJEXT='o' -PACKAGE='libteletone' -PACKAGE_BUGREPORT='BUG-REPORT-ADDRESS' -PACKAGE_NAME='FULL-PACKAGE-NAME' -PACKAGE_STRING='FULL-PACKAGE-NAME VERSION' -PACKAGE_TARNAME='full-package-name' -PACKAGE_VERSION='VERSION' -PATH_SEPARATOR=':' -RANLIB='ranlib' -SET_MAKE='' -SHELL='/bin/sh' -STRIP='strip' -VERSION='0.1' -ac_ct_AR='ar' -ac_ct_CC='gcc' -ac_ct_CXX='g++' -ac_ct_F77='f95' -ac_ct_RANLIB='ranlib' -ac_ct_STRIP='strip' -am__fastdepCC_FALSE='#' -am__fastdepCC_TRUE='' -am__fastdepCXX_FALSE='#' -am__fastdepCXX_TRUE='' -am__include='include' -am__leading_dot='.' -am__quote='' -am__tar='${AMTAR} chof - "$$tardir"' -am__untar='${AMTAR} xf -' -bindir='${exec_prefix}/bin' -build='i686-pc-linux-gnu' -build_alias='' -build_cpu='i686' -build_os='linux-gnu' -build_vendor='pc' -datadir='${prefix}/share' -exec_prefix='${prefix}' -host='i686-pc-linux-gnu' -host_alias='' -host_cpu='i686' -host_os='linux-gnu' -host_vendor='pc' -includedir='${prefix}/include' -infodir='${prefix}/info' -install_sh='/root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/install-sh' -libdir='${exec_prefix}/lib' -libexecdir='${exec_prefix}/libexec' -localstatedir='${prefix}/var' -mandir='${prefix}/man' -mkdir_p='mkdir -p --' -oldincludedir='/usr/include' -prefix='/usr/local' -program_transform_name='s,x,x,' -sbindir='${exec_prefix}/sbin' -sharedstatedir='${prefix}/com' -sysconfdir='${prefix}/etc' -target_alias='' - -## ----------- ## -## confdefs.h. ## -## ----------- ## - -#define HAVE_DIRENT_H 1 -#define HAVE_DLFCN_H 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_MALLOC 1 -#define HAVE_MEMORY_H 1 -#define HAVE_STDINT_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRFTIME 1 -#define HAVE_STRINGS_H 1 -#define HAVE_STRING_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_UNISTD_H 1 -#define PACKAGE "libteletone" -#define PACKAGE_BUGREPORT "BUG-REPORT-ADDRESS" -#define PACKAGE_NAME "FULL-PACKAGE-NAME" -#define PACKAGE_STRING "FULL-PACKAGE-NAME VERSION" -#define PACKAGE_TARNAME "full-package-name" -#define PACKAGE_VERSION "VERSION" -#define RETSIGTYPE void -#define STDC_HEADERS 1 -#define STDC_HEADERS 1 -#define TIME_WITH_SYS_TIME 1 -#define VERSION "0.1" -#endif -#ifdef __cplusplus -extern "C" void std::exit (int) throw (); using std::exit; - -configure: exit 0 diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/text-base/config.status.svn-base b/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/text-base/config.status.svn-base deleted file mode 100644 index b7cede5..0000000 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/.svn/text-base/config.status.svn-base +++ /dev/null @@ -1,980 +0,0 @@ -#! /bin/sh -# Generated by configure. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=${CONFIG_SHELL-/bin/sh} -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi -DUALCASE=1; export DUALCASE # for MKS sh - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - -exec 6>&1 - -# Open the log real soon, to keep \$[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - -This file was extended by FULL-PACKAGE-NAME $as_me VERSION, which was -generated by GNU Autoconf 2.59. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 -config_files=" Makefile" -config_commands=" depfiles" - -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Configuration commands: -$config_commands - -Report bugs to ." -ac_cs_version="\ -FULL-PACKAGE-NAME config.status VERSION -configured by ./configure, generated by GNU Autoconf 2.59, - with options \"\" - -Copyright (C) 2003 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." -srcdir=. -INSTALL="/usr/bin/install -c" -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` - ac_shift=: - ;; - -*) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_option=$1 - ac_need_defaults=false;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" - ac_need_defaults=false;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -if $ac_cs_recheck; then - echo "running /bin/sh ./configure " $ac_configure_extra_args " --no-create --no-recursion" >&6 - exec /bin/sh ./configure $ac_configure_extra_args --no-create --no-recursion -fi - -# -# INIT-COMMANDS section. -# - -AMDEP_TRUE="" ac_aux_dir="." - -for ac_config_target in $ac_config_targets -do - case "$ac_config_target" in - # Handling of arguments. - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason to put it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Create a temporary directory, and hook for its removal unless debugging. -$debug || -{ - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} - -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./confstat$$-$RANDOM - (umask 077 && mkdir $tmp) -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - - -# -# CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t$/@;t t/; /@;t t$/s/[\\&,]/\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t$/,;t t/' >$tmp/subs.sed <<\CEOF -s,@SHELL@,/bin/sh,;t t -s,@PATH_SEPARATOR@,:,;t t -s,@PACKAGE_NAME@,FULL-PACKAGE-NAME,;t t -s,@PACKAGE_TARNAME@,full-package-name,;t t -s,@PACKAGE_VERSION@,VERSION,;t t -s,@PACKAGE_STRING@,FULL-PACKAGE-NAME VERSION,;t t -s,@PACKAGE_BUGREPORT@,BUG-REPORT-ADDRESS,;t t -s,@exec_prefix@,${prefix},;t t -s,@prefix@,/usr/local,;t t -s,@program_transform_name@,s,x,x,,;t t -s,@bindir@,${exec_prefix}/bin,;t t -s,@sbindir@,${exec_prefix}/sbin,;t t -s,@libexecdir@,${exec_prefix}/libexec,;t t -s,@datadir@,${prefix}/share,;t t -s,@sysconfdir@,${prefix}/etc,;t t -s,@sharedstatedir@,${prefix}/com,;t t -s,@localstatedir@,${prefix}/var,;t t -s,@libdir@,${exec_prefix}/lib,;t t -s,@includedir@,${prefix}/include,;t t -s,@oldincludedir@,/usr/include,;t t -s,@infodir@,${prefix}/info,;t t -s,@mandir@,${prefix}/man,;t t -s,@build_alias@,,;t t -s,@host_alias@,,;t t -s,@target_alias@,,;t t -s,@DEFS@,-DPACKAGE_NAME=\"FULL-PACKAGE-NAME\" -DPACKAGE_TARNAME=\"full-package-name\" -DPACKAGE_VERSION=\"VERSION\" -DPACKAGE_STRING=\"FULL-PACKAGE-NAME\ VERSION\" -DPACKAGE_BUGREPORT=\"BUG-REPORT-ADDRESS\" -DPACKAGE=\"libteletone\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DHAVE_DIRENT_H=1 -DSTDC_HEADERS=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DRETSIGTYPE=void -DHAVE_STRFTIME=1 ,;t t -s,@ECHO_C@,,;t t -s,@ECHO_N@,-n,;t t -s,@ECHO_T@,,;t t -s,@LIBS@,,;t t -s,@INSTALL_PROGRAM@,${INSTALL},;t t -s,@INSTALL_SCRIPT@,${INSTALL},;t t -s,@INSTALL_DATA@,${INSTALL} -m 644,;t t -s,@CYGPATH_W@,echo,;t t -s,@PACKAGE@,libteletone,;t t -s,@VERSION@,0.1,;t t -s,@ACLOCAL@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run aclocal-1.9,;t t -s,@AUTOCONF@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoconf,;t t -s,@AUTOMAKE@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run automake-1.9,;t t -s,@AUTOHEADER@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoheader,;t t -s,@MAKEINFO@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run makeinfo,;t t -s,@install_sh@,/root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/install-sh,;t t -s,@STRIP@,strip,;t t -s,@ac_ct_STRIP@,strip,;t t -s,@INSTALL_STRIP_PROGRAM@,${SHELL} $(install_sh) -c -s,;t t -s,@mkdir_p@,mkdir -p --,;t t -s,@AWK@,gawk,;t t -s,@SET_MAKE@,,;t t -s,@am__leading_dot@,.,;t t -s,@AMTAR@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run tar,;t t -s,@am__tar@,${AMTAR} chof - "$$tardir",;t t -s,@am__untar@,${AMTAR} xf -,;t t -s,@CC@,gcc,;t t -s,@CFLAGS@,-g -O2,;t t -s,@LDFLAGS@,,;t t -s,@CPPFLAGS@,,;t t -s,@ac_ct_CC@,gcc,;t t -s,@EXEEXT@,,;t t -s,@OBJEXT@,o,;t t -s,@DEPDIR@,.deps,;t t -s,@am__include@,include,;t t -s,@am__quote@,,;t t -s,@AMDEP_TRUE@,,;t t -s,@AMDEP_FALSE@,#,;t t -s,@AMDEPBACKSLASH@,\,;t t -s,@CCDEPMODE@,depmode=gcc3,;t t -s,@am__fastdepCC_TRUE@,,;t t -s,@am__fastdepCC_FALSE@,#,;t t -s,@build@,i686-pc-linux-gnu,;t t -s,@build_cpu@,i686,;t t -s,@build_vendor@,pc,;t t -s,@build_os@,linux-gnu,;t t -s,@host@,i686-pc-linux-gnu,;t t -s,@host_cpu@,i686,;t t -s,@host_vendor@,pc,;t t -s,@host_os@,linux-gnu,;t t -s,@EGREP@,grep -E,;t t -s,@LN_S@,ln -s,;t t -s,@ECHO@,echo,;t t -s,@AR@,ar,;t t -s,@ac_ct_AR@,ar,;t t -s,@RANLIB@,ranlib,;t t -s,@ac_ct_RANLIB@,ranlib,;t t -s,@CPP@,gcc -E,;t t -s,@CXX@,g++,;t t -s,@CXXFLAGS@,-g -O2,;t t -s,@ac_ct_CXX@,g++,;t t -s,@CXXDEPMODE@,depmode=gcc3,;t t -s,@am__fastdepCXX_TRUE@,,;t t -s,@am__fastdepCXX_FALSE@,#,;t t -s,@CXXCPP@,g++ -E,;t t -s,@F77@,f95,;t t -s,@FFLAGS@,-g -O2,;t t -s,@ac_ct_F77@,f95,;t t -s,@LIBTOOL@,$(SHELL) $(top_builddir)/libtool,;t t -s,@LIBOBJS@,,;t t -s,@LTLIBOBJS@,,;t t -CEOF - - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` - fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat - fi -fi # test -n "$CONFIG_FILES" - -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; - esac - - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_builddir$INSTALL ;; - esac - - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } - sed "/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -} - -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -s,@INSTALL@,$ac_INSTALL,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi - -done - -# -# CONFIG_COMMANDS section. -# -for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue - ac_dest=`echo "$ac_file" | sed 's,:.*,,'` - ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_dir=`(dirname "$ac_dest") 2>/dev/null || -$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_dest" : 'X\(//\)[^/]' \| \ - X"$ac_dest" : 'X\(//\)$' \| \ - X"$ac_dest" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_dest" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - - { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 -echo "$as_me: executing $ac_dest commands" >&6;} - case $ac_dest in - depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # So let's grep whole file. - if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then - dirpart=`(dirname "$mf") 2>/dev/null || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`(dirname "$file") 2>/dev/null || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p $dirpart/$fdir - else - as_dir=$dirpart/$fdir - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 -echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} - { (exit 1); exit 1; }; }; } - - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done - ;; - esac -done - -{ (exit 0); exit 0; } diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/Makefile b/ssmg/sangoma_mgd.trunk/lib/libteletone/Makefile index cd4df29..55bb61c 100644 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/Makefile +++ b/ssmg/sangoma_mgd.trunk/lib/libteletone/Makefile @@ -100,14 +100,14 @@ DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print -ACLOCAL = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run aclocal-1.9 +ACLOCAL = ${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run aclocal-1.9 AMDEP_FALSE = # AMDEP_TRUE = -AMTAR = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run tar +AMTAR = ${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run tar AR = ar -AUTOCONF = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoconf -AUTOHEADER = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoheader -AUTOMAKE = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run automake-1.9 +AUTOCONF = ${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoconf +AUTOHEADER = ${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoheader +AUTOMAKE = ${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run automake-1.9 AWK = gawk CC = gcc CCDEPMODE = depmode=gcc3 @@ -139,7 +139,7 @@ LIBS = LIBTOOL = $(SHELL) $(top_builddir)/libtool LN_S = ln -s LTLIBOBJS = -MAKEINFO = ${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run makeinfo +MAKEINFO = ${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run makeinfo OBJEXT = o PACKAGE = libteletone PACKAGE_BUGREPORT = BUG-REPORT-ADDRESS @@ -183,7 +183,7 @@ host_os = linux-gnu host_vendor = pc includedir = ${prefix}/include infodir = ${prefix}/info -install_sh = /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/install-sh +install_sh = /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localstatedir = ${prefix}/var diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/config.log b/ssmg/sangoma_mgd.trunk/lib/libteletone/config.log index fe6897d..2fbe48d 100644 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/config.log +++ b/ssmg/sangoma_mgd.trunk/lib/libteletone/config.log @@ -12,9 +12,9 @@ generated by GNU Autoconf 2.59. Invocation command line was hostname = tesla uname -m = i686 -uname -r = 2.6.18-8.el5 +uname -r = 2.6.18-8.1.15.el5 uname -s = Linux -uname -v = #1 SMP Thu Mar 15 19:57:35 EDT 2007 +uname -v = #1 SMP Mon Oct 22 08:32:04 EDT 2007 /usr/bin/uname -p = unknown /bin/uname -X = unknown @@ -36,7 +36,6 @@ PATH: /sbin PATH: /bin PATH: /usr/sbin PATH: /usr/bin -PATH: /usr/X11R6/bin PATH: /usr/sbin/scripts PATH: /root/bin PATH: /usr/sbin/scripts @@ -46,6 +45,7 @@ PATH: /usr/sbin/scripts ## Core tests. ## ## ----------- ## +configure:1416: loading cache /dev/null configure:1551: checking for a BSD-compatible install configure:1606: result: /usr/bin/install -c configure:1617: checking whether build environment is sane @@ -861,15 +861,15 @@ lt_lt_cv_sys_global_symbol_to_cdecl='"sed -n -e '\''s/^. .* \\(.*\\)\$/extern in ## Output variables. ## ## ----------------- ## -ACLOCAL='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run aclocal-1.9' +ACLOCAL='${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run aclocal-1.9' AMDEPBACKSLASH='\' AMDEP_FALSE='#' AMDEP_TRUE='' -AMTAR='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run tar' +AMTAR='${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run tar' AR='ar' -AUTOCONF='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoconf' -AUTOHEADER='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoheader' -AUTOMAKE='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run automake-1.9' +AUTOCONF='${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoconf' +AUTOHEADER='${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoheader' +AUTOMAKE='${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run automake-1.9' AWK='gawk' CC='gcc' CCDEPMODE='depmode=gcc3' @@ -901,7 +901,7 @@ LIBS='' LIBTOOL='$(SHELL) $(top_builddir)/libtool' LN_S='ln -s' LTLIBOBJS='' -MAKEINFO='${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run makeinfo' +MAKEINFO='${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run makeinfo' OBJEXT='o' PACKAGE='libteletone' PACKAGE_BUGREPORT='BUG-REPORT-ADDRESS' @@ -945,7 +945,7 @@ host_os='linux-gnu' host_vendor='pc' includedir='${prefix}/include' infodir='${prefix}/info' -install_sh='/root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/install-sh' +install_sh='/root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/install-sh' libdir='${exec_prefix}/lib' libexecdir='${exec_prefix}/libexec' localstatedir='${prefix}/var' diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/config.status b/ssmg/sangoma_mgd.trunk/lib/libteletone/config.status index b7cede5..8f1476f 100755 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/config.status +++ b/ssmg/sangoma_mgd.trunk/lib/libteletone/config.status @@ -480,12 +480,12 @@ s,@INSTALL_DATA@,${INSTALL} -m 644,;t t s,@CYGPATH_W@,echo,;t t s,@PACKAGE@,libteletone,;t t s,@VERSION@,0.1,;t t -s,@ACLOCAL@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run aclocal-1.9,;t t -s,@AUTOCONF@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoconf,;t t -s,@AUTOMAKE@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run automake-1.9,;t t -s,@AUTOHEADER@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoheader,;t t -s,@MAKEINFO@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run makeinfo,;t t -s,@install_sh@,/root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/install-sh,;t t +s,@ACLOCAL@,${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run aclocal-1.9,;t t +s,@AUTOCONF@,${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoconf,;t t +s,@AUTOMAKE@,${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run automake-1.9,;t t +s,@AUTOHEADER@,${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run autoheader,;t t +s,@MAKEINFO@,${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run makeinfo,;t t +s,@install_sh@,/root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/install-sh,;t t s,@STRIP@,strip,;t t s,@ac_ct_STRIP@,strip,;t t s,@INSTALL_STRIP_PROGRAM@,${SHELL} $(install_sh) -c -s,;t t @@ -493,7 +493,7 @@ s,@mkdir_p@,mkdir -p --,;t t s,@AWK@,gawk,;t t s,@SET_MAKE@,,;t t s,@am__leading_dot@,.,;t t -s,@AMTAR@,${SHELL} /root/3.1/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run tar,;t t +s,@AMTAR@,${SHELL} /root/3.2/wanpipe/ssmg/sangoma_mgd.trunk/lib/libteletone/missing --run tar,;t t s,@am__tar@,${AMTAR} chof - "$$tardir",;t t s,@am__untar@,${AMTAR} xf -,;t t s,@CC@,gcc,;t t diff --git a/ssmg/sangoma_mgd.trunk/lib/libteletone/src/.svn/entries b/ssmg/sangoma_mgd.trunk/lib/libteletone/src/.svn/entries index 14abbf8..b426d00 100644 --- a/ssmg/sangoma_mgd.trunk/lib/libteletone/src/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/lib/libteletone/src/.svn/entries @@ -1,7 +1,7 @@ 8 dir -24 +58 https://www.sangomapbx.com:/svn/sangoma_mgd/trunk/lib/libteletone/src https://www.sangomapbx.com:/svn/sangoma_mgd diff --git a/ssmg/sangoma_mgd.trunk/sangoma_mgd.c b/ssmg/sangoma_mgd.trunk/sangoma_mgd.c index 08a068b..6b9c034 100644 --- a/ssmg/sangoma_mgd.trunk/sangoma_mgd.c +++ b/ssmg/sangoma_mgd.trunk/sangoma_mgd.c @@ -1,13 +1,49 @@ /********************************************************************************* * sangoma_mgd.c -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards * - * Copyright 05-07, Nenad Corbic + * Copyright 05-08, Nenad Corbic * Anthony Minessale II * * This program is free software, distributed under the terms of * the GNU General Public License * * ============================================= + * v1.26 Nenad Corbic + * Jan 18 2007 + * Fixed hangup after invalid Answer or Ack Session + * Can cause double use of setup id - now fixed + * Update on autoacm on accept check for acked. + * + * v1.25 Nenad Corbic + * Dec 31 2007 + * Removed UDP Resync it can cause skb_over errors. + * Moved RDNIS message to higher debug level + * + * v1.24 Nenad Corbic + * Nov 30 2007 + * Bug fix on return code on ALL ckt busy + * + * v1.23 Nenad Corbic + * Bug fix on socket open. Check for retun code >= 0 + * + * v1.22 Nenad Corbic + * Nov 27 2007 + * Updated DTMF Tx function + * Fixed - dtmf tx without voice + * Fxied - dtmf clipping. + * + * v1.21 Nenad Corbic + * Nov 25 2007 + * Major unit testing of each state + * Numerous bug fixes for non autoacm mode. + * Changed "Channel-Name" to tg/cic + * Added compile option WANPIPE_CHAN_NAME to change Asterisk channel + * name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE}) + * instead of WOOMERA (for example) + * + * v1.20 Nenad Corbic + * Added option for Auto ACM response mode. + * * v1.19 Nenad Corbic * Configurable DTMF * Bug fix in release codes (all ckt busy) @@ -99,7 +135,7 @@ static struct woomera_interface woomera_dead_dev; #endif -#define SMG_VERSION "v1.19" +#define SMG_VERSION "v1.26" /* enable early media */ #if 1 @@ -112,11 +148,9 @@ static struct woomera_interface woomera_dead_dev; #define SMG_DTMF_RATE 8000 #if 0 -#warning "NENAD: MEDIA SHUTDOWN" #define MEDIA_SOCK_SHUTDOWN 1 #endif - #ifdef DOTRACE static int tc = 0; #endif @@ -132,9 +166,11 @@ static int tc = 0; hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; #endif +#undef SMG_CALLING_NAME + const char WELCOME_TEXT[] = "================================================================================\n" -"Sangoma Media Gateway Daemon v1.19 \n" +"Sangoma Media Gateway Daemon v1.26 \n" "TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n" "Copyright 2005, 2006, 2007 \n" "Nenad Corbic , Anthony Minessale II \n" @@ -147,6 +183,7 @@ const char WELCOME_TEXT[] = static int master_reset=0; static int coredump=1; +static int autoacm=1; static int launch_media_tdm_thread(struct woomera_interface *woomera); static int launch_woomera_thread(struct woomera_interface *woomera); @@ -614,7 +651,7 @@ static void add_listener(struct woomera_interface *woomera) } -#ifdef SMG_DTMF_ENABLE + static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) { struct media_session *ms = woomera_get_ms(woomera); @@ -662,7 +699,6 @@ static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) ms->skip_read_frames = 200; return 0; } -#endif static struct woomera_interface *alloc_woomera(void) { @@ -767,6 +803,41 @@ static int waitfor_socket(int fd, int timeout, int flags) return res; } + +static int waitfor_tx_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if (pfds[0].revents & POLLOUT) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + + #else static int waitfor_socket(int fd, int timeout, int flags) @@ -880,7 +951,6 @@ static struct media_session *media_session_new(struct woomera_interface *woomera woomera_set_ms(woomera,ms); ms->woomera = woomera; -#ifdef SMG_DTMF_ENABLE /* Setup artificial DTMF stuff */ memset(&ms->tone_session, 0, sizeof(ms->tone_session)); if (teletone_init_session(&ms->tone_session, 0, NULL, NULL)) { @@ -893,7 +963,6 @@ static struct media_session *media_session_new(struct woomera_interface *woomera ms->tone_session.wait = server.dtmf_off * (ms->tone_session.rate / 1000); teletone_dtmf_detect_init (&ms->dtmf_detect, SMG_DTMF_RATE); -#endif } else { log_printf(0, server.log, "ERROR: Memory Alloc Failed [w%ig%i]!\n", @@ -909,10 +978,8 @@ static void media_session_free(struct media_session *ms) free(ms->ip); } -#ifdef SMG_DTMF_ENABLE teletone_destroy_session(&ms->tone_session); switch_buffer_destroy(&ms->dtmf_buffer); -#endif ms->woomera = NULL; @@ -931,7 +998,7 @@ static int create_udp_socket(struct media_session *ms, char *local_ip, int local memset(&ms->remote_hp, 0, sizeof(ms->remote_hp)); memset(&ms->local_hp, 0, sizeof(ms->local_hp)); - if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0))) { + if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { gethostbyname_r(ip, &ms->remote_hp, buf, sizeof(buf), &result, &err); gethostbyname_r(local_ip, &ms->local_hp, local_buf, sizeof(local_buf), &local_result, &err); if (result && local_result) { @@ -983,7 +1050,7 @@ static int next_media_port(void) return port; } -#ifdef SMG_DTMF_ENABLE + static int woomera_dtmf_transmit(struct media_session *ms, int mtu) { @@ -996,6 +1063,9 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) int slin_len = mtu*2; short *data; int used; + int res; + int err; + int txdtmf=0; memset(&hdrframe,0,sizeof(hdrframe)); if (!ms->dtmf_buffer) { @@ -1003,8 +1073,17 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) } for (;;) { + + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + break; + } -#ifdef CODEC_LAW_DEFAULT + res = waitfor_tx_socket(ms->sangoma_sock, -1, POLLERR | POLLOUT); + if (res <= 0) { + break; + } + +#ifdef CODEC_LAW_DEFAULT pthread_mutex_lock(&woomera->dtmf_lock); if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { @@ -1018,14 +1097,6 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) if (bread <= 0) { break; } - -#if 0 - if (bread < slin_len) { - while (bread < slin_len) { - dtmf[bread++] = 0xFF; - } - } -#endif log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes MTU=%i Coding=%i Used=%i\n", woomera->interface,bread,mtu,ms->hw_coding,used); @@ -1041,24 +1112,23 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) } } - sangoma_sendmsg_socket(ms->sangoma_sock, + err=sangoma_sendmsg_socket(ms->sangoma_sock, &hdrframe, sizeof(hdrframe), dtmf_law, mtu, 0); - - ms->skip_write_frames+=server.dtmf_intr_ch; + + if (err != mtu) { + log_printf(0, woomera->log, "Error: Failed to TX to TDM API on DTMF (err=%i mtu=%i)!\n",err,mtu); + } + + txdtmf++; + ms->skip_write_frames++; #else ... pthread_mutex_lock(&woomera->dtmf_lock); bread = switch_buffer_read(ms->dtmf_buffer, dtmf, mtu); pthread_mutex_unlock(&woomera->dtmf_lock); - if (bread < mtu) { - while (bread < mtu) { - dtmf[bread++] = 0; - } - } - log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes\n", woomera->interface,bread); @@ -1066,14 +1136,18 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) &hdrframe, sizeof(hdrframe), dtmf, mtu, 0); + txdtmf++; ms->skip_write_frames++; #endif - return 0; + } - - return -1; + + if (txdtmf) { + return 0; + } else { + return -1; + } } -#endif static void media_loop_run(struct media_session *ms) { @@ -1246,6 +1320,7 @@ static void *media_thread_run(void *obj) struct woomera_event wevent; wanpipe_tdm_api_t tdm_api; FILE *tx_fd=NULL; + int sock_timeout=200; if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || @@ -1400,7 +1475,7 @@ static void *media_thread_run(void *obj) local_port, WOOMERA_LINE_SEPERATOR, woomera->interface, - WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, WOOMERA_RECORD_SEPERATOR ); #endif @@ -1426,12 +1501,23 @@ static void *media_thread_run(void *obj) while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && !woomera_test_flag(woomera, WFLAG_MEDIA_END) && !woomera_test_flag(woomera, WFLAG_HANGUP) && - (res = waitfor_socket(ms->udp_sock, 1000, POLLERR | POLLIN)) >= 0) { + (res = waitfor_socket(ms->udp_sock, sock_timeout, POLLERR | POLLIN)) >= 0) { unsigned int fromlen = sizeof(struct sockaddr_in); if (res == 0) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + log_printf(4, server.log, "%s: UDP Sock Timeout !!!\n", woomera->interface); /* NENAD Timeout thus just continue */ @@ -1451,6 +1537,8 @@ static void *media_thread_run(void *obj) if (packet_len > 0) { +#if 0 +/* NC: This can cause skb_over panic must be retested */ if (packet_len != sangoma_frame_len && ms->udp_sync_cnt <= 5) { /* Assume that we will always receive SLINEAR here */ sangoma_tdm_set_usr_period(ms->sangoma_sock, @@ -1458,7 +1546,7 @@ static void *media_thread_run(void *obj) sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); - log_printf(0, server.log, + log_printf(3, server.log, "%s: UDP TDM Period ReSync to Len=%i %ims (udp=%i) \n", woomera->interface,sangoma_frame_len, sangoma_frame_len/codec_sample,packet_len); @@ -1475,23 +1563,27 @@ static void *media_thread_run(void *obj) } } - -#ifdef SMG_DTMF_ENABLE - if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { - /* For sanity sake if we are doing the out test - * dont take any chances force tx udp data */ - if (!server.out_tx_test) { +#endif + if (!server.out_tx_test) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + /* For sanity sake if we are doing the out test + * dont take any chances force tx udp data */ if (ms->skip_write_frames > 0) { - ms->skip_write_frames--; + ms->skip_write_frames--; } continue; + } else { + sock_timeout=200; } - } - if (ms->skip_write_frames > 0) { - ms->skip_write_frames--; - continue; - } -#endif + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + continue; + } + + } if (server.out_tx_test && tx_fd && fread((void*)udp_frame, @@ -1799,6 +1891,10 @@ static struct woomera_interface * launch_woomera_loop_thread(call_signal_event_t } woomera_set_interface(woomera,callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = woomera; + pthread_mutex_unlock(&server.process_lock); if (launch_woomera_thread(woomera)) { pthread_mutex_lock(&server.process_lock); @@ -1878,10 +1974,12 @@ static int woomera_message_parse(struct woomera_interface *woomera, struct woome } ysleep(1000); continue; + } else if (res < 0) { log_printf(3, woomera->log, WOOMERA_DEBUG_PREFIX - "%s error during packet retry #%d\n", - woomera->interface, loops); + "%s error during packet retry (err=%i) Loops#%d (%s)\n", + woomera->interface, res, loops, + strerror(errno)); return res; } else if (loops) { ysleep(100000); @@ -2024,8 +2122,10 @@ static struct woomera_interface *pull_from_holding_tank(int index, int span , in struct woomera_interface *woomera = NULL; if (index < 1 || index >= CORE_TANK_LEN) { - log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", - __FUNCTION__,index); + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } return NULL; } @@ -2047,18 +2147,25 @@ static struct woomera_interface *pull_from_holding_tank(int index, int span , in return woomera; } -static void clear_from_holding_tank(int index) +static void clear_from_holding_tank(int index, struct woomera_interface *woomera) { if (index < 1 || index >= CORE_TANK_LEN) { - log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", - __FUNCTION__,index); + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } return; } pthread_mutex_lock(&server.ht_lock); if (server.holding_tank[index] == &woomera_dead_dev) { - server.holding_tank[index] = NULL; + server.holding_tank[index] = NULL; + } else if (woomera && server.holding_tank[index] == woomera) { + server.holding_tank[index] = NULL; + } else if (server.holding_tank[index]) { + log_printf(0, server.log, "Error: Holding tank index %i not cleared %p !\n", + index, server.holding_tank[index]); } pthread_mutex_unlock(&server.ht_lock); @@ -2070,8 +2177,10 @@ static struct woomera_interface *peek_from_holding_tank(int index) struct woomera_interface *woomera = NULL; if (index < 1 || index >= CORE_TANK_LEN) { - log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", - __FUNCTION__,index); + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } return NULL; } @@ -2117,7 +2226,7 @@ static int add_to_holding_tank(struct woomera_interface *woomera) log_printf(0, server.log, "\nCritical Error failed to obtain a TANK INDEX\n"); return 0; } - + server.holding_tank[next] = woomera; woomera->timeout = time(NULL) + 100; @@ -2164,6 +2273,7 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, log_printf(4, server.log,"ERROR: Failed to Launch Call [%s]\n", woomera->interface); +#if 0 new_woomera_event_printf(&wevent, "501 call was cancelled!%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2171,7 +2281,7 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - +#endif new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id: %s%s" @@ -2202,6 +2312,18 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); } else { + + if (accept) { + if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + } + if (answer) { struct media_session *ms; @@ -2212,6 +2334,16 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, pthread_mutex_unlock(&woomera->ms_lock); if (ms) { + + if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + isup_exec_command(woomera->span, woomera->chan, -1, @@ -2262,27 +2394,38 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - } + } - return 0; + return 0; } -static int handle_woomera_call_start (struct woomera_interface *woomera, - struct woomera_message *wmsg) +static int handle_woomera_call_start (struct woomera_interface *woomera, + struct woomera_message *wmsg) { - char *raw = woomera_message_header(wmsg, "raw-audio"); - call_signal_event_t event; - char *calling = woomera_message_header(wmsg, "local-number"); + char *raw = woomera_message_header(wmsg, "raw-audio"); + call_signal_event_t event; + char *calling = woomera_message_header(wmsg, "local-number"); +#ifdef SMG_CALLING_NAME + char *calling_name = woomera_message_header(wmsg, "local-name"); +#endif char *presentation = woomera_message_header(wmsg, "Presentation"); char *screening = woomera_message_header(wmsg, "Screening"); char *rdnis = woomera_message_header(wmsg, "RDNIS"); - //char *callerid = woomera_message_header(wmsg, "local-name"); char *called = wmsg->callid; char *grp = wmsg->callid; char *p; + int cause = 34; int tg = 0; if (smg_check_all_busy()) { + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); socket_printf(woomera->socket, "405 SMG Server All Ckt Busy!%s", WOOMERA_RECORD_SEPERATOR); log_printf(3, woomera->log, "SMG Server Full %d (ckt busy cnt=%i)\n", @@ -2301,12 +2444,22 @@ static int handle_woomera_call_start (struct woomera_interface *woomera, } } + woomera->trunk_group=tg; + if (raw) { woomera_set_raw(woomera, raw); } woomera->index = add_to_holding_tank(woomera); if (woomera->index < 1) { + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); socket_printf(woomera->socket, "405 SMG Server All Tanks Busy!%s", WOOMERA_RECORD_SEPERATOR); @@ -2335,16 +2488,34 @@ static int handle_woomera_call_start (struct woomera_interface *woomera, if (rdnis && strlen(rdnis)) { strncpy((char*)event.redirection_string,rdnis, sizeof(event.redirection_string)-1); - log_printf(0,server.log,"RDNIS %s\n", rdnis); + log_printf(3,server.log,"RDNIS %s\n", rdnis); } +#ifdef SMG_CALLING_NAME + if (calling_name) { + strncpy((char*)event.calling_name,calling_name, + sizeof(event.calling_name)-1); + } +#endif + event.trunk_group = tg; + if (call_signal_connection_write(&server.mcon, &event) <= 0) { log_printf(0, server.log, "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", strerror(errno)); + + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "405 SMG Signalling Contestion!%s", WOOMERA_RECORD_SEPERATOR); @@ -2364,6 +2535,8 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ { int answer = 0, media = 0, accept=0; char *unique_id; + int cause=0; + if (!strcasecmp(wmsg->command, "call")) { @@ -2378,8 +2551,9 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ err=handle_woomera_call_start(woomera,wmsg); if (err) { - woomera_clear_flag(woomera, WFLAG_RUNNING); + woomera_set_flag(woomera, WFLAG_HANGUP); } + return; } else if (!strcasecmp(wmsg->command, "bye") || !strcasecmp(wmsg->command, "quit")) { @@ -2453,15 +2627,24 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ return; } + unique_id = woomera_message_header(wmsg, "Unique-Call-Id"); if (!unique_id) { - socket_printf(woomera->socket, "400 Error no unique id found %s", - WOOMERA_RECORD_SEPERATOR); - log_printf(0,server.log,"Woomera RX Even (%s) without unique id!\n",wmsg->command); - if (!strcasecmp(wmsg->command, "hangup")) { - woomera_clear_flag(woomera, WFLAG_RUNNING); - } + cause=111; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "400 Woomera cmd without uniquie id%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2,server.log,"Woomera RX Event (%s) without unique id!\n",wmsg->command); + woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2479,15 +2662,24 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ "WOOMERA Got CMD %s Span=%d Chan=%d from session %s\n", wmsg->command,span,chan,unique_id); - if (smg_validate_span_chan(span,chan) != 0) { - socket_printf(woomera->socket, - "400 Error invalid span chan in session! %s", + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Invalid span/chan in session%s" WOOMERA_RECORD_SEPERATOR); - - log_printf(0, woomera->log, - "WOOMERA Error invalid span chan in session %s\n", + + log_printf(2, woomera->log, + "WOOMERA Warning invalid span chan in session %s %s\n", wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2498,11 +2690,22 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ if (session_woomera) { pthread_mutex_unlock(&server.process_lock); - socket_printf(woomera->socket, "400 Error channel in use! %s", + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Session not found%s" WOOMERA_RECORD_SEPERATOR); + - log_printf(0, woomera->log, "WOOMERA Error channel in use %s\n", + log_printf(0, woomera->log, "WOOMERA Error channel in use %s %s\n", wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2510,11 +2713,23 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ strncmp(session,unique_id,sizeof(woomera->session))){ pthread_mutex_unlock(&server.process_lock); - socket_printf(woomera->socket, "400 Error no such session %s", + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Invalid/Expired Session%s" WOOMERA_RECORD_SEPERATOR); - log_printf(0, woomera->log, + + log_printf(3, woomera->log, "WOOMERA Warning: Cmd=%s with invalid session %s (orig=%s)\n", wmsg->command,unique_id,session?session:"N/A"); + woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2534,20 +2749,31 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ } else if (strncmp(woomera->session,unique_id,sizeof(woomera->session))) { - socket_printf(woomera->socket, "400 Error session missmatch %s", + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Session Mis-match%s" WOOMERA_RECORD_SEPERATOR); + woomera_set_flag(woomera, WFLAG_HANGUP); return; } - + if (!strcasecmp(wmsg->command, "dtmf")) { log_printf(3, woomera->log, "WOOMERA CMD: DTMF Received: [%s] Digit %s Body %s\n", woomera->interface, wmsg->command_args, wmsg->body); -#ifdef SMG_DTMF_ENABLE wanpipe_send_dtmf(woomera,wmsg->body); -#endif + socket_printf(woomera->socket, "200 DTMF OK%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2573,6 +2799,7 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ woomera->interface,cause); if (smg_validate_span_chan(span,chan) != 0) { + socket_printf(woomera->socket, "405 No Such Channel%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2650,13 +2877,20 @@ static void handle_call_answer(call_signal_event_t *event) woomera = server.process_table[event->span][event->chan].dev; pthread_mutex_unlock(&server.process_lock); - if (woomera && woomera->raw) { + if (woomera) { char callid[80]; struct woomera_event wevent; + if (!woomera->raw) { + log_printf(1, server.log, "Refusing to answer call with no media!\n"); + kill++; + goto handle_call_answer_end; + } + if (woomera_test_flag(woomera, WFLAG_ANSWER)) { log_printf(1, server.log, "Refusing to double-answer a call!\n"); - return; + kill++; + goto handle_call_answer_end; } woomera_set_flag(woomera, WFLAG_ANSWER); @@ -2664,7 +2898,7 @@ static void handle_call_answer(call_signal_event_t *event) if (woomera->span != event->span || woomera->chan != event->chan) { log_printf(1, server.log, "Refusing to start media on a different channel from the one we agreed on.!\n"); kill++; - return; + goto handle_call_answer_end; } if (woomera_test_flag(woomera, WFLAG_HANGUP)) { @@ -2680,6 +2914,7 @@ static void handle_call_answer(call_signal_event_t *event) if (err) { log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", woomera->interface); +#if 0 new_woomera_event_printf(&wevent, "501 call was cancelled!%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2687,7 +2922,8 @@ static void handle_call_answer(call_signal_event_t *event) WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - +#endif + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id: %s%s" "Q931-Cause-Code: %d%s" @@ -2706,9 +2942,6 @@ static void handle_call_answer(call_signal_event_t *event) - woomera_set_flag(woomera, - (WFLAG_HANGUP|WFLAG_MEDIA_END)); - woomera_clear_flag(woomera, WFLAG_RUNNING); kill++; } #endif @@ -2731,30 +2964,22 @@ static void handle_call_answer(call_signal_event_t *event) kill++; } -#if 0 +handle_call_answer_end: + if (kill) { - call_signal_event_t oevent; - if (woomera) { - if (woomera_test_flag(woomera, WFLAG_HANGUP)) { - /* Do not hangup if this call was already hungup */ - return; - } - - woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_set_flag(woomera,WFLAG_MEDIA_END); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(1, server.log, "Sent CALL STOP to Answer without session [w%dg%d]\n", + event->span+1, event->chan+1); } - - isup_exec_command(event->span, - event->chan, - -1, - SIGBOOST_EVENT_CALL_STOPPED, - SIGBOOST_RELEASE_CAUSE_NORMAL); - - log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", - event->span+1, event->chan+1); } -#endif - } static void handle_call_start_ack(call_signal_event_t *event) @@ -2763,7 +2988,7 @@ static void handle_call_start_ack(call_signal_event_t *event) struct woomera_event wevent; int kill = 0; - if ((woomera = pull_from_holding_tank(event->call_setup_id,event->span,event->chan))) { + if ((woomera = peek_from_holding_tank(event->call_setup_id))) { char callid[80]; if (woomera_test_flag(woomera, WFLAG_HANGUP)) { @@ -2771,11 +2996,14 @@ static void handle_call_start_ack(call_signal_event_t *event) kill++; } else { int err, span, chan; + + pull_from_holding_tank(event->call_setup_id,event->span,event->chan); sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); span = event->span; chan = event->chan; + woomera_set_flag(woomera,WFLAG_CALL_ACKED); woomera_set_interface(woomera, callid); pthread_mutex_lock(&server.process_lock); @@ -2793,6 +3021,8 @@ static void handle_call_start_ack(call_signal_event_t *event) log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", woomera->interface); + +#if 0 new_woomera_event_printf(&wevent, "501 call was cancelled!%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2800,7 +3030,8 @@ static void handle_call_start_ack(call_signal_event_t *event) WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - +#endif + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id:%s%s" "Q931-Cause-Code: %d%s" @@ -2816,9 +3047,7 @@ static void handle_call_start_ack(call_signal_event_t *event) ); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - - woomera_set_flag(woomera,WFLAG_MEDIA_END); - woomera_clear_flag(woomera, WFLAG_RUNNING); + kill++; } #endif @@ -2832,10 +3061,14 @@ static void handle_call_start_ack(call_signal_event_t *event) enqueue_event(woomera, &wevent,EVENT_FREE_DATA); new_woomera_event_printf(&wevent, "EVENT PROCEED w%dg%d%s" + "Channel-Name: g%d/%d%s" "Unique-Call-Id: %s%s", event->span+1, event->chan+1, WOOMERA_LINE_SEPERATOR, + woomera->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, woomera->session, WOOMERA_RECORD_SEPERATOR ); @@ -2853,30 +3086,20 @@ static void handle_call_start_ack(call_signal_event_t *event) kill++; } -#if 0 if (kill) { - call_signal_event_t oevent; - if (woomera) { - if (woomera_test_flag(woomera, WFLAG_HANGUP)) { - /* Do not hangup if this call was already hungup */ - return; - } - - woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_set_flag(woomera,WFLAG_MEDIA_END); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(1, server.log, "Sent CALL STOP to CALL START ACK without session [w%dg%d]\n", + event->span+1, event->chan+1); } - - isup_exec_command(event->span, - event->chan, - -1, - SIGBOOST_EVENT_CALL_STOPPED, - SIGBOOST_RELEASE_CAUSE_NORMAL); - - log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", - event->span+1, event->chan+1); } -#endif - } static void handle_call_start_nack(call_signal_event_t *event) @@ -2897,37 +3120,21 @@ static void handle_call_start_nack(call_signal_event_t *event) } if (event->call_setup_id > 0) { - woomera=pull_from_holding_tank(event->call_setup_id,-1,-1); + woomera=peek_from_holding_tank(event->call_setup_id); } if (woomera) { struct woomera_event wevent; - woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); - woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); - isup_exec_command(0, - 0, - event->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0); - - - if (woomera_test_flag(woomera, WFLAG_HANGUP)) { log_printf(0, server.log, "Event CALL START NACK on hungup call [%d]!\n", event->call_setup_id); + ack++; } else { - woomera_set_cause_topbx(woomera,event->release_cause); - - new_woomera_event_printf(&wevent, "501 Error!%s" - "Unique-Call-Id: %s%s", - WOOMERA_LINE_SEPERATOR, - woomera->session, - WOOMERA_RECORD_SEPERATOR); - - enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + woomera_set_cause_topbx(woomera,event->release_cause); + woomera_set_flag(woomera, (WFLAG_HANGUP|WFLAG_HANGUP_NACK_ACK)); new_woomera_event_printf(&wevent, "EVENT HANGUP w%dg%d%s" "Unique-Call-Id: %s%s" @@ -2945,55 +3152,58 @@ static void handle_call_start_nack(call_signal_event_t *event) ); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + woomera_set_flag(woomera, WFLAG_HANGUP); woomera_clear_flag(woomera, WFLAG_RUNNING); + /* Do not ack here, let woomera thread ack it */ + ack=0; } - - /* We already did the NACK */ - ack=0; + } else if (event->call_setup_id == 0 && smg_validate_span_chan(event->span,event->chan) == 0) { pthread_mutex_lock(&server.process_lock); woomera = server.process_table[event->span][event->chan].dev; - server.process_table[event->span][event->chan].dev=NULL; + + if (woomera) { + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } else if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* At this point call is already hang up */ + woomera=NULL; + } else { + /* At this point call is already hang up */ + woomera=NULL; + } + } + memset(server.process_table[event->span][event->chan].session, 0,SMG_SESSION_NAME_SZ); pthread_mutex_unlock(&server.process_lock); + if (woomera) { - log_printf(0, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", + log_printf(2, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", woomera->span+1,woomera->chan+1,woomera,woomera->ms); - - woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); - woomera_set_flag(woomera, - (WFLAG_HANGUP|WFLAG_MEDIA_END)); - isup_exec_command(event->span, - event->chan, - event->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0); - -#ifdef MEDIA_SOCK_SHUTDOWN - pthread_mutex_lock(&woomera->ms_lock); - if (woomera->ms) { - shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); - shutdown(woomera->ms->udp_sock, SHUT_RDWR); + if (!woomera_test_flag(woomera,WFLAG_HANGUP)){ + woomera_set_cause_topbx(woomera,event->release_cause); } - pthread_mutex_unlock(&woomera->ms_lock); -#endif - - /* We already did the NACK */ + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END|WFLAG_HANGUP_NACK_ACK)); + + /* Nack Ack will be sent by the woomera thread */ ack=0; } else { - + /* Valid state when we are not in autoacm mode */ ack++; - log_printf(0, server.log, "Error: No Device on valid Span Chan [w%dg%d]!\n", + log_printf(3, server.log, "Event: NACK no woomera on span chan [w%dg%d]!\n", event->span+1, event->chan+1); } @@ -3003,12 +3213,14 @@ static void handle_call_start_nack(call_signal_event_t *event) event->call_setup_id, event->span+1, event->chan+1); ack++; } - + + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { log_printf(0, server.log, "WARNING: All ckt busy!\n"); smg_all_ckt_busy(); } + #warning "Ignoring CALL GAP" #if 0 if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP) { @@ -3024,26 +3236,29 @@ static void handle_call_start_nack(call_signal_event_t *event) span=event->span; chan=event->chan; } + isup_exec_command(span, chan, event->call_setup_id, SIGBOOST_EVENT_CALL_START_NACK_ACK, 0); - + if (!woomera) { log_printf(2, server.log, "Event (NACK ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", event->event_id,event->call_setup_id, event->span+1, event->chan+1); + } } } static void handle_call_loop_start(call_signal_event_t *event) { - struct woomera_interface *woomera; + char callid[20]; + char *session; pthread_mutex_lock(&server.process_lock); if (server.process_table[event->span][event->chan].dev) { - + isup_exec_command(event->span, event->chan, -1, @@ -3059,7 +3274,14 @@ static void handle_call_loop_start(call_signal_event_t *event) return; } - pthread_mutex_unlock(&server.process_lock); + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + woomera=launch_woomera_loop_thread(event); if (woomera == NULL) { @@ -3073,6 +3295,7 @@ static void handle_call_loop_start(call_signal_event_t *event) event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); } + woomera_set_flag(woomera,WFLAG_CALL_ACKED); return; } @@ -3084,6 +3307,7 @@ static void handle_call_start(call_signal_event_t *event) char *session; pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { isup_exec_command(event->span, @@ -3099,7 +3323,6 @@ static void handle_call_start(call_signal_event_t *event) pthread_mutex_unlock(&server.process_lock); return; - } sprintf(callid, "w%dg%d", event->span+1,event->chan+1); @@ -3109,13 +3332,13 @@ static void handle_call_start(call_signal_event_t *event) server.process_table[event->span][event->chan].dev = NULL; pthread_mutex_unlock(&server.process_lock); - - isup_exec_command(event->span, - event->chan, - -1, - SIGBOOST_EVENT_CALL_START_ACK, - 0); - + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } new_woomera_event_printf(&wevent, "EVENT INCOMING w%dg%d%s" "Unique-Call-Id: %s%s" @@ -3124,7 +3347,7 @@ static void handle_call_start(call_signal_event_t *event) "Protocol: SS7%s" "User-Agent: sangoma_mgd%s" "Local-Number: %s%s" - "Channel-Name: SMG-g%ds%dc%d%s" + "Channel-Name: g%d/%d%s" "Trunk-Group: %d%s" "Presentation: %d%s" "Screening: %d%s" @@ -3137,15 +3360,18 @@ static void handle_call_start(call_signal_event_t *event) WOOMERA_LINE_SEPERATOR, event->calling_number_digits, WOOMERA_LINE_SEPERATOR, +#ifdef SMG_CALLING_NAME + event->calling_name, +#else "", +#endif WOOMERA_LINE_SEPERATOR, WOOMERA_LINE_SEPERATOR, WOOMERA_LINE_SEPERATOR, event->called_number_digits, WOOMERA_LINE_SEPERATOR, event->trunk_group+1, - event->span+1, - event->chan+1, + (event->span*31)+event->chan+1, WOOMERA_LINE_SEPERATOR, event->trunk_group+1, WOOMERA_LINE_SEPERATOR, @@ -3166,12 +3392,19 @@ static void handle_call_start(call_signal_event_t *event) memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); pthread_mutex_unlock(&server.process_lock); - - isup_exec_command(event->span, - event->chan, - -1, - SIGBOOST_EVENT_CALL_STOPPED, - SIGBOOST_RELEASE_CAUSE_BUSY); + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_BUSY); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + } log_printf(0, server.log, "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", @@ -3197,42 +3430,45 @@ static void handle_restart_ack(call_signal_connection_t *mcon,call_signal_event_ static void handle_call_stop(call_signal_event_t *event) { struct woomera_interface *woomera; - + int ack=0; + pthread_mutex_lock(&server.process_lock); woomera = server.process_table[event->span][event->chan].dev; - server.process_table[event->span][event->chan].dev=NULL; + if (woomera) { + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } else if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* At this point call is already hangup */ + woomera=NULL; + } else { + /* At this point call is already hangup */ + woomera=NULL; + } + } memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); pthread_mutex_unlock(&server.process_lock); if (woomera) { - + woomera_set_cause_topbx(woomera,event->release_cause); + + woomera_set_flag(woomera, + (WFLAG_MEDIA_END|WFLAG_HANGUP|WFLAG_HANGUP_ACK)); - woomera_set_flag(woomera, - (WFLAG_MEDIA_END|WFLAG_HANGUP)); - - woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); - - isup_exec_command(event->span, - event->chan, - -1, - SIGBOOST_EVENT_CALL_STOPPED_ACK, - 0); - -#ifdef MEDIA_SOCK_SHUTDOWN - pthread_mutex_lock(&woomera->ms_lock); - if (woomera->ms) { - shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); - shutdown(woomera->ms->udp_sock, SHUT_RDWR); - } - pthread_mutex_unlock(&woomera->ms_lock); -#endif + /* We have to close the socket because + At this point we are release span chan */ log_printf(3, server.log, "Event CALL STOP on w%dg%d ptr=%p ms=%p\n", woomera->span+1,woomera->chan+1,woomera,woomera->ms); } else { - + ack++; + } + + + if (ack) { /* At this point we have already sent our STOP so its safe to ACK */ isup_exec_command(event->span, event->chan, @@ -3291,6 +3527,7 @@ static void handle_call_stop_ack(call_signal_event_t *event) return; } + static void handle_call_start_nack_ack(call_signal_event_t *event) { @@ -3300,17 +3537,33 @@ static void handle_call_start_nack_ack(call_signal_event_t *event) woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + } else { + log_printf(0, server.log, + "Event NACK ACK [w%dg%d] with valid span/chan no dev!\n", + event->span+1, event->chan+1); + } + } else { log_printf(2, server.log, "Event NACK ACK referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", event->span+1, event->chan+1, event->call_setup_id); } -#if 1 if (event->call_setup_id > 0) { - clear_from_holding_tank(event->call_setup_id); + clear_from_holding_tank(event->call_setup_id, NULL); } -#endif /* No need for us to do any thing here */ return; @@ -3615,6 +3868,8 @@ static void woomera_loop_thread_run(struct woomera_interface *woomera) continue; } + + woomera_clear_flag(woomera, WFLAG_RUNNING); log_printf(2, server.log, "Woomera Session: For Loop Test exiting %s\n",woomera->interface); @@ -3638,8 +3893,8 @@ static void *woomera_thread_run(void *obj) //smg_get_current_priority(&policy,&priority); - log_printf(2, server.log, "WOOMERA session for started (ptr=%p : loop=%i)(%i:%i)\n", - woomera,woomera->loop_tdm,policy,priority); + log_printf(2, server.log, "WOOMERA session started (ptr=%p : loop=%i)(%i:%i) Index=%i\n", + woomera,woomera->loop_tdm,policy,priority, woomera->index); pthread_mutex_lock(&server.thread_count_lock); server.thread_count++; @@ -3715,7 +3970,7 @@ static void *woomera_thread_run(void *obj) "WOOMERA session (ptr=%p) Call Timedout ! [%s] (Timeout=%d)\n", woomera,woomera->interface,woomera->timeout); - /* NENAD Let the Index check run a nak */ + /* Let the Index check below send a NACK */ if (woomera->index) { woomera_set_flag(woomera, WFLAG_HANGUP); } @@ -3761,21 +4016,38 @@ woomera_session_close: /* The call was not HUNGUP. This is the last check, If the call is valid, hungup the call if the call was never up the keep going */ - woomera_set_flag(woomera, WFLAG_HANGUP); + if (smg_validate_span_chan(span,chan) == 0) { if (!woomera->index) { - woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); - isup_exec_command(span, - chan, - -1, - SIGBOOST_EVENT_CALL_STOPPED, - woomera->q931_rel_cause_tosig); - - log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] ptr=%p\n", - span+1, chan+1,woomera->interface,woomera); + if (autoacm || woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + woomera->q931_rel_cause_tosig); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT); + + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } else { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + woomera->q931_rel_cause_tosig); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT); + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_START_NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } } else { log_printf(0, woomera->log, "Woomera Not Sent CALL STOPPED - Instead NACK [w%dg%d] [%s] ptr=%p\n", span+1, chan+1,woomera->interface,woomera); @@ -3785,15 +4057,19 @@ woomera_session_close: /* This can happend if an outgoing call times out or gets hungup before it gets acked. Its not a failure */ + if (!woomera->index) { - log_printf(3, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", + /* In this case we really failed to tx STOP */ + log_printf(0, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", span+1, chan+1, woomera->interface, woomera->index, woomera); + } } - + + woomera_set_flag(woomera, WFLAG_HANGUP); + } woo_re_hangup: - /* We must send a STOP ACK to boost telling it that we are done */ if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { @@ -3824,7 +4100,7 @@ woo_re_hangup: } woomera_clear_flag(woomera, WFLAG_HANGUP_ACK); - + woomera_set_flag(woomera, WFLAG_HANGUP); } if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { @@ -3846,7 +4122,17 @@ woo_re_hangup: "Sent (Nack Ack) to SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] ptr=%p\n", span+1,chan+1,woomera->interface,woomera); - + woomera->index=0; + + } else if (woomera->index) { + isup_exec_command(0, + 0, + woomera->index, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + woomera->index=0; + } else { log_printf(0, woomera->log, "FAILED: Sent (Nack Ack) SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", @@ -3860,8 +4146,7 @@ woo_re_hangup: if (woomera->index) { int index = woomera->index; - int timeout_cnt=0; - int overall_cnt=0; + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id: %s%s" @@ -3887,58 +4172,68 @@ woo_re_hangup: } if (peek_from_holding_tank(index)) { - + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); isup_exec_command(0, 0, index, SIGBOOST_EVENT_CALL_START_NACK, 0); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT); log_printf(2, woomera->log, "Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] .. WAITING FOR NACK ACK\n", index); - - /* SMG sent NACK to boost, however we have to wait - for boost to give us the ACK back before we - release resources. */ - - while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { - timeout_cnt++; - if (timeout_cnt > 40000) { //10sec timeout - timeout_cnt=0; - overall_cnt++; - log_printf(0, woomera->log, - "Waiting for NACK ACK [Setup ID: %d] ... \n", - index); - } - - if (overall_cnt > 10) { //100sec timeotu - woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); - break; - } - - if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { - break; - } - - usleep(5000); - sched_yield(); - } - - if (overall_cnt > 10) { + } else { + log_printf(1, woomera->log, + "Error Failed to Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] - index stale!\n", + index); + } + } + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent NACK to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //30sec timeout + timeout_cnt=0; + overall_cnt++; log_printf(0, woomera->log, - "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", - index); - - } else { - log_printf(2, woomera->log, - "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", - index); + "Waiting for NACK ACK [Setup ID: %d] ... \n", + woomera->index); + } + if (overall_cnt > 10) { //300sec timeotu + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + break; } + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { + break; + } + + usleep(5000); + sched_yield(); } + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", + index); + + } else { + log_printf(2, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", + index); + + } } if (woomera_test_flag(woomera, WFLAG_EVENT)){ @@ -3964,7 +4259,7 @@ woo_re_hangup: while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { timeout_cnt++; - if (timeout_cnt > 40000) { //10sec timeout + if (timeout_cnt > 4000) { //10sec timeout timeout_cnt=0; overall_cnt++; log_printf(0, woomera->log, @@ -3987,18 +4282,18 @@ woo_re_hangup: usleep(5000); sched_yield(); } + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); - if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { - if (overall_cnt > 10) { - log_printf(0, woomera->log, - "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", - woomera->interface,woomera->index_hold); + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); - } else { - log_printf(2, woomera->log, - "Wait GOT STOPPED ACK [%s] [id=%i]... \n", - woomera->interface,woomera->index_hold); - } + } else { + log_printf(2, woomera->log, + "Wait GOT STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); } } @@ -4058,7 +4353,7 @@ woo_re_hangup: * value until the end of the call. Tank is only * used on outgoing calls. */ if (woomera->index_hold >= 1) { - clear_from_holding_tank(woomera->index_hold); + clear_from_holding_tank(woomera->index_hold, woomera); woomera->index_hold=0; } @@ -4282,6 +4577,12 @@ static int configure_server(void) if (max > 0) { server.max_calls = max; } + } else if (!strcasecmp(var, "autoacm")) { + int max = atoi(val); + if (max >= 0) { + autoacm=max; + } + } else if (!strcasecmp(var, "media_ip")) { strncpy(server.media_ip, val, sizeof(server.media_ip) -1); } else { @@ -4297,7 +4598,7 @@ static int configure_server(void) server.dtmf_off=SMG_DTMF_OFF; } if (server.dtmf_intr_ch == -1) { - server.dtmf_intr_ch = server.dtmf_on/server.dtmf_off; + server.dtmf_intr_ch = 0; } server.dtmf_size=(server.dtmf_on+server.dtmf_off)*10*2; @@ -4625,7 +4926,7 @@ static int woomera_startup(int argc, char **argv) } fprintf(stderr, "%s", WELCOME_TEXT); - log_printf(0, stderr, "Woomera STARTUP Complete.\n"); + log_printf(0, stderr, "Woomera STARTUP Complete. [AutoACM=%i]\n",autoacm); return 1; } diff --git a/ssmg/sangoma_mgd.trunk/sangoma_mgd.conf.sample b/ssmg/sangoma_mgd.trunk/sangoma_mgd.conf.sample index 12f131b..0f71566 100644 --- a/ssmg/sangoma_mgd.trunk/sangoma_mgd.conf.sample +++ b/ssmg/sangoma_mgd.trunk/sangoma_mgd.conf.sample @@ -52,3 +52,10 @@ dtmf_off_duration => 10 #on configuration. Default chunk size #is 10ms. #dtmf_inter_ch_duration => 0 + +#Enable/Disable Auto ISUP ACM +#response to an incoming ss7 call. +#0-Disable +#1-Enable (Default) +autoacm => 1 + diff --git a/ssmg/sangoma_mgd.trunk/sangoma_mgd.h b/ssmg/sangoma_mgd.trunk/sangoma_mgd.h index d0b5319..a938601 100644 --- a/ssmg/sangoma_mgd.trunk/sangoma_mgd.h +++ b/ssmg/sangoma_mgd.trunk/sangoma_mgd.h @@ -40,21 +40,16 @@ #include #endif -/* Enable DTMF encoding by default */ -#ifndef SMG_DTMF_ENABLE -#define SMG_DTMF_ENABLE 1 -#endif -#ifdef SMG_DTMF_ENABLE #include #include -#endif #define WOOMERA_MAX_SPAN 16 #define WOOMERA_MAX_CHAN 31 #define SMG_SESSION_NAME_SZ 100 +#define SMG_CHAN_NAME_SZ 20 #define PIDFILE "/var/run/sangoma_mgd.pid" #define CORE_EVENT_LEN 512 @@ -95,6 +90,9 @@ typedef enum { WFLAG_WAIT_FOR_NACK_ACK = (1 << 13), WFLAG_WAIT_FOR_STOPPED_ACK = (1 << 14), WFLAG_RAW_MEDIA_STARTED = (1 << 15), + WFLAG_CALL_ACKED = (1 << 16), + WFLAG_WAIT_FOR_NACK_ACK_SENT = (1 << 17), + WFLAG_WAIT_FOR_STOPPED_ACK_SENT = (1 << 18), } WFLAGS; typedef enum { @@ -169,11 +167,9 @@ struct media_session { hp_tdm_api_chan_t *tdmchan; #endif -#ifdef SMG_DTMF_ENABLE teletone_dtmf_detect_state_t dtmf_detect; teletone_generation_session_t tone_session; switch_buffer_t *dtmf_buffer; -#endif }; @@ -224,6 +220,7 @@ struct woomera_interface { int index_hold; int span; int chan; + int trunk_group; int call_count; int q931_rel_cause_tosig; int q931_rel_cause_topbx; @@ -349,7 +346,16 @@ static inline int smg_check_all_busy(void) static inline void smg_all_ckt_busy(void) { - server.all_ckt_busy+=1000; + + if (server.call_count*10 < 1500) { + server.all_ckt_busy+=1500; + } else { + server.all_ckt_busy+=server.call_count*15; + } + + if (server.all_ckt_busy > 60000) { + server.all_ckt_busy = 60000; + } #if 0 if (server.all_ckt_busy >= 5) { @@ -530,6 +536,10 @@ static inline void woomera_set_cause_topbx(struct woomera_interface *woomera, in cause=SIGBOOST_RELEASE_CAUSE_NORMAL; } + if (cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { + cause=34; + } + woomera->q931_rel_cause_topbx=cause; } diff --git a/ssmg/sangoma_mgd.trunk/sangoma_mgd.orig.c b/ssmg/sangoma_mgd.trunk/sangoma_mgd.orig.c new file mode 100644 index 0000000..ff7c8ca --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/sangoma_mgd.orig.c @@ -0,0 +1,5012 @@ +/********************************************************************************* + * sangoma_mgd.c -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards + * + * Copyright 05-07, Nenad Corbic + * Anthony Minessale II + * + * This program is free software, distributed under the terms of + * the GNU General Public License + * + * ============================================= + * v1.24 Nenad Corbic + * Nov 30 2007 + * Bug fix on return code on ALL ckt busy + * + * v1.23 Nenad Corbic + * Bug fix on socket open. Check for retun code >= 0 + * + * v1.22 Nenad Corbic + * Nov 27 2007 + * Updated DTMF Tx function + * Fixed - dtmf tx without voice + * Fxied - dtmf clipping. + * + * v1.21 Nenad Corbic + * Nov 25 2007 + * Major unit testing of each state + * Numerous bug fixes for non autoacm mode. + * Changed "Channel-Name" to tg/cic + * Added compile option WANPIPE_CHAN_NAME to change Asterisk channel + * name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE}) + * instead of WOOMERA (for example) + * + * v1.20 Nenad Corbic + * Added option for Auto ACM response mode. + * + * v1.19 Nenad Corbic + * Configurable DTMF + * Bug fix in release codes (all ckt busy) + * + * v1.18 Nenad Corbic + * Added new rel cause support based on + * digits instead of strings. + * + * v1.17 Nenad Corbic + * Added session support + * + * v1.16 Nenad Corbic + * Added hwec disable on loop ccr + * + * v1.15 Nenad Corbic + * Updated DTMF Locking + * Added delay between digits + * + * v1.14 Nenad Corbic + * Updated DTMF Library + * Fixed DTMF synchronization + * + * v1.13 Nenad Corbic + * Woomera OPAL Dialect + * Added Congestion control + * Added SCTP + * Added priority ISUP queue + * Fixed presentation + * + * v1.12 Nenad Corbic + * Fixed CCR + * Removed socket shutdown on end call. + * Let Media thread shutodwn sockets. + * + * v1.11 Nenad Corbic + * Fixed Remote asterisk/woomera connection + * Increased socket timeouts + * + * v1.10 Nenad Corbic + * Added Woomera OPAL dialect. + * Start montor thread in priority + * + * v1.9 Nenad Corbic + * Added Loop mode for ccr + * Added remote debug enable + * Fixed syslog logging. + * + * v1.8 Nenad Corbic + * Added a ccr loop mode for each channel. + * Boost can set any channel in loop mode + * + * v1.7 Nenad Corbic + * Pass trunk group number to incoming call + * chan woomera will use it to append to context + * name. Added presentation feature. + * + * v1.6 Nenad Corbic + * Use only ALAW and MLAW not SLIN. + * This reduces the load quite a bit. + * Send out ALAW/ULAW format on HELLO message. + * RxTx Gain is done now in chan_woomera. + * + * v1.5 Nenad Corbic + * Bug fix in START_NACK_ACK handling. + * When we receive START_NACK we must alwasy pull tank before + * we send out NACK_ACK this way we will not try to send NACK + * ourself. + *********************************************************************************/ + +#include "sangoma_mgd.h" +#include "q931_cause.h" + + +#define USE_SYSLOG 1 +#define CODEC_LAW_DEFAULT 1 + +#ifdef CODEC_LAW_DEFAULT +static uint32_t codec_sample=8; +#else +static uint32_t codec_sample=16; +#endif + +static char ps_progname[]="sangoma_mgd"; + +static struct woomera_interface woomera_dead_dev; + +#if 0 +#define DOTRACE +#endif + + +#define SMG_VERSION "v1.24" + +/* enable early media */ +#if 1 +#define WOOMERA_EARLY_MEDIA 1 +#endif + + +#define SMG_DTMF_ON 60 +#define SMG_DTMF_OFF 10 +#define SMG_DTMF_RATE 8000 + +#if 0 +#define MEDIA_SOCK_SHUTDOWN 1 +#endif + +#ifdef DOTRACE +static int tc = 0; +#endif + +#if 0 +#warning "NENAD: HPTDM API" +#define WP_HPTDM_API 1 +#else +#undef WP_HPTDM_API +#endif + +#ifdef WP_HPTDM_API +hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; +#endif + +#undef SMG_CALLING_NAME + +const char WELCOME_TEXT[] = +"================================================================================\n" +"Sangoma Media Gateway Daemon v1.24 \n" +"TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n" +"Copyright 2005, 2006, 2007 \n" +"Nenad Corbic , Anthony Minessale II \n" +"This program is free software, distributed under the terms of\n" +"the GNU General Public License\n" +"================================================================================\n" +""; + + +static int master_reset=0; + +static int coredump=1; +static int autoacm=1; + +static int launch_media_tdm_thread(struct woomera_interface *woomera); +static int launch_woomera_thread(struct woomera_interface *woomera); +static struct woomera_interface *alloc_woomera(void); + +q931_cause_to_str_array_t q931_cause_to_str_array[255]; + + +#if 0 +static uint32_t string_to_release(char *code) +{ + if (code) { + if (!strcasecmp(code, "CHANUNAVAIL")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "INVALID")) { + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "ERROR")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + if (!strcasecmp(code, "CONGESTION")) { + //return SIGBOOST_RELEASE_CAUSE_BUSY; + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "BUSY")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "NOANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "ANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NORMAL; + } + + if (!strcasecmp(code, "CANCEL")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "UNKNOWN")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + } + return SIGBOOST_RELEASE_CAUSE_NORMAL; +} + +static char * release_to_string(uint32_t rel_cause) +{ + switch (rel_cause) { + + case SIGBOOST_RELEASE_CAUSE_UNDEFINED: + return "UNKNOWN"; + case SIGBOOST_RELEASE_CAUSE_NORMAL: + return "NORMAL"; + case SIGBOOST_RELEASE_CAUSE_BUSY: + return "BUSY"; + case SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST: + return "CHANUNAVAIL"; + case SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET: + return "CANCEL"; + case SIGBOOST_RELEASE_CAUSE_NOANSWER: + return "NOANSWER"; + case SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT: + return "TIMEOUT"; + case SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY: + return "CONGESTION"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_SMALL: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_SMALL: + return "ERROR"; + } + + return "NORMAL"; +} +#endif + + + +void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return; + } + + if (level && level > server.debug) { + return; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + } else { + char date[80] = ""; + struct tm now; + time_t epoch; + + if (time(&epoch) && localtime_r(&epoch, &now)) { + strftime(date, sizeof(date), "%Y-%m-%d %T", &now); + } + +#ifdef USE_SYSLOG + syslog(LOG_DEBUG | LOG_LOCAL2, data); +#else + fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data); +#endif + free(data); + } +#ifndef USE_SYSLOG + fflush(fp); +#endif +} + + + + +static int isup_exec_command(int span, int chan, int id, int cmd, int cause) +{ + call_signal_event_t oevent; + int retry=5; + + call_signal_event_init(&oevent, cmd, chan, span); + oevent.release_cause = cause; + + if (id >= 0) { + oevent.call_setup_id = id; + } +isup_exec_cmd_retry: + if (call_signal_connection_write(&server.mcon, &oevent) <= 0){ + + --retry; + if (retry <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket: %s\n", + strerror(errno)); + return -1; + } else { + log_printf(0, server.log, + "System Warning: Failed to tx on ISUP socket: %s :retry %i\n", + strerror(errno),retry); + } + + goto isup_exec_cmd_retry; + } + + return 0; +} + +static int socket_printf(int socket, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return -1; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + log_printf(0, server.log, "Crtical ERROR: Memory Error!\n"); + } else { + int err; + int len = strlen(data); + err=send(socket, data, strlen(data), 0); + if (err != strlen(data)) { + log_printf(2, server.log, "ERROR: Failed to send data to woomera socket(%i): err=%i len=%d %s\n", + socket,err,len,strerror(errno)); + ret = err; + } else { + ret = 0; + } + + free(data); + } + + return ret; +} + + + +static int woomera_next_pair(struct woomera_config *cfg, char **var, char **val) +{ + int ret = 0; + char *p, *end; + + *var = *val = NULL; + + for(;;) { + cfg->lineno++; + + if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) { + ret = 0; + break; + } + + *var = cfg->buf; + + if (**var == '[' && (end = strchr(*var, ']'))) { + *end = '\0'; + (*var)++; + strncpy(cfg->category, *var, sizeof(cfg->category) - 1); + continue; + } + + if (**var == '#' || **var == '\n' || **var == '\r') { + continue; + } + + if ((end = strchr(*var, '#'))) { + *end = '\0'; + end--; + } else if ((end = strchr(*var, '\n'))) { + if (*end - 1 == '\r') { + end--; + } + *end = '\0'; + } + + p = *var; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *var = p; + + if (!(*val = strchr(*var, '='))) { + ret = -1; + log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); + continue; + } else { + p = *val - 1; + *(*val) = '\0'; + (*val)++; + if (*(*val) == '>') { + *(*val) = '\0'; + (*val)++; + } + + while ((*p == ' ' || *p == '\t') && p != *var) { + *p = '\0'; + p--; + } + + p = *val; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *val = p; + ret = 1; + break; + } + } + + return ret; + +} + + +#if 0 +static void woomera_set_span_chan(struct woomera_interface *woomera, int span, int chan) +{ + pthread_mutex_lock(&woomera->vlock); + woomera->span = span; + woomera->chan = chan; + pthread_mutex_unlock(&woomera->vlock); + +} +#endif + + +static struct woomera_event *new_woomera_event_printf(struct woomera_event *ebuf, char *fmt, ...) +{ + struct woomera_event *event = NULL; + int ret = 0; + va_list ap; + + if (ebuf) { + event = ebuf; + } else if (!(event = new_woomera_event())) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + return NULL; + } else { + return NULL; + } + + va_start(ap, fmt); +#ifdef SOLARIS + event->data = (char *) malloc(2048); + vsnprintf(event->data, 2048, fmt, ap); +#else + ret = vasprintf(&event->data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + destroy_woomera_event(&event, EVENT_FREE_DATA); + return NULL; + } + + return event; + +} + +static struct woomera_event *woomera_clone_event(struct woomera_event *event) +{ + struct woomera_event *clone; + + if (!(clone = new_woomera_event())) { + return NULL; + } + + memcpy(clone, event, sizeof(*event)); + clone->next = NULL; + clone->data = strdup(event->data); + + return clone; +} + +static void enqueue_event(struct woomera_interface *woomera, + struct woomera_event *event, + event_args free_data) +{ + struct woomera_event *ptr, *clone = NULL; + + assert(woomera != NULL); + assert(event != NULL); + + if (!(clone = woomera_clone_event(event))) { + log_printf(0, server.log, "Error Cloning Event\n"); + return; + } + + pthread_mutex_lock(&woomera->queue_lock); + + for (ptr = woomera->event_queue; ptr && ptr->next ; ptr = ptr->next); + + if (ptr) { + ptr->next = clone; + } else { + woomera->event_queue = clone; + } + + pthread_mutex_unlock(&woomera->queue_lock); + + woomera_set_flag(woomera, WFLAG_EVENT); + + if (free_data && event->data) { + /* The event has been duplicated, the original data + * should be freed */ + free(event->data); + event->data=NULL; + } +} + +static char *dequeue_event(struct woomera_interface *woomera) +{ + struct woomera_event *event; + char *data = NULL; + + if (!woomera) { + return NULL; + } + + pthread_mutex_lock(&woomera->queue_lock); + if (woomera->event_queue) { + event = woomera->event_queue; + woomera->event_queue = event->next; + data = event->data; + pthread_mutex_unlock(&woomera->queue_lock); + + destroy_woomera_event(&event, EVENT_KEEP_DATA); + return data; + } + pthread_mutex_unlock(&woomera->queue_lock); + + return data; +} + + +static int enqueue_event_on_listeners(struct woomera_event *event) +{ + struct woomera_listener *ptr; + int x = 0; + + assert(event != NULL); + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + enqueue_event(ptr->woomera, event, EVENT_KEEP_DATA); + x++; + } + pthread_mutex_unlock(&server.listen_lock); + + return x; +} + + +static void del_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *ptr, *last = NULL; + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + if (ptr->woomera == woomera) { + if (last) { + last->next = ptr->next; + } else { + server.listeners = ptr->next; + } + free(ptr); + break; + } + last = ptr; + } + pthread_mutex_unlock(&server.listen_lock); +} + +static void add_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *new; + + pthread_mutex_lock(&server.listen_lock); + + if ((new = malloc(sizeof(*new)))) { + memset(new, 0, sizeof(*new)); + new->woomera = woomera; + new->next = server.listeners; + server.listeners = new; + } else { + log_printf(0, server.log, "Memory Error adding listener!\n"); + } + + pthread_mutex_unlock(&server.listen_lock); +} + + + +static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) +{ + struct media_session *ms = woomera_get_ms(woomera); + char *cur = NULL; + int wrote = 0; + int err; + + if (!ms) { + return -EINVAL; + } + + if (!ms->dtmf_buffer) { + log_printf(3, woomera->log, "Allocate DTMF Buffer...."); + + err=switch_buffer_create_dynamic(&ms->dtmf_buffer, 1024, server.dtmf_size, 0); + + if (err != 0) { + log_printf(0, woomera->log, "Failed to allocate DTMF Buffer!\n"); + return -ENOMEM; + } else { + log_printf(3, woomera->log, "SUCCESS!\n"); + } + + } + + log_printf(3, woomera->log, "Sending DTMF %s\n",digits); + for (cur = digits; *cur; cur++) { + if ((wrote = teletone_mux_tones(&ms->tone_session, + &ms->tone_session.TONES[(int)*cur]))) { + + pthread_mutex_lock(&woomera->dtmf_lock); + + err=switch_buffer_write(ms->dtmf_buffer, ms->tone_session.buffer, wrote * 2); + + pthread_mutex_unlock(&woomera->dtmf_lock); + + log_printf(3, woomera->log, "Sending DTMF %s Wrote=%i (err=%i)\n", + digits,wrote*2,err); + } else { + log_printf(0, woomera->log, "Error: Sending DTMF %s (err=%i)\n", + digits,wrote); + } + } + + ms->skip_read_frames = 200; + return 0; +} + +static struct woomera_interface *alloc_woomera(void) +{ + struct woomera_interface *woomera = NULL; + + if ((woomera = malloc(sizeof(struct woomera_interface)))) { + + memset(woomera, 0, sizeof(struct woomera_interface)); + + woomera->chan = -1; + woomera->span = -1; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->q931_rel_cause_topbx=SIGBOOST_RELEASE_CAUSE_NORMAL; + woomera->q931_rel_cause_tosig=SIGBOOST_RELEASE_CAUSE_NORMAL; + + woomera_set_interface(woomera, "w-1g-1"); + + + + } + + return woomera; + +} + + +static struct woomera_interface *new_woomera_interface(int socket, struct sockaddr_in *sock_addr, int len) +{ + struct woomera_interface *woomera = NULL; + + if (socket < 0) { + log_printf(0, server.log, "Critical: Invalid Socket on new interface!\n"); + return NULL; + } + + if ((woomera = alloc_woomera())) { + if (socket >= 0) { + no_nagle(socket); + woomera->socket = socket; + } + + if (sock_addr && len) { + memcpy(&woomera->addr, sock_addr, len); + } + } + + return woomera; + +} + +static char *woomera_message_header(struct woomera_message *wmsg, char *key) +{ + int x = 0; + char *value = NULL; + + for (x = 0 ; x < wmsg->last ; x++) { + if (!strcasecmp(wmsg->names[x], key)) { + value = wmsg->values[x]; + break; + } + } + + return value; +} + + +#if 1 + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + + +static int waitfor_tx_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if (pfds[0].revents & POLLOUT) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + + +#else + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags | errflags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & errflags)) { + res = -1; + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X)!\n", + pfds[0].revents); +#endif + res = -1; + } + } + + return res; +} + +#endif + +#if 1 +static int waitfor_2sockets(int fda, int fdb, char *a, char *b, int timeout) +{ + struct pollfd pfds[2]; + int res = 0; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + if (fda < 0 || fdb < 0) { + return -1; + } + + *a=0; + *b=0; + + memset(pfds, 0, sizeof(pfds)); + pfds[0].fd = fda; + pfds[1].fd = fdb; + pfds[0].events = POLLIN | errflags; + pfds[1].events = POLLIN | errflags; + if ((res = poll(pfds, 2, timeout)) > 0) { + res = 1; + if ((pfds[0].revents & errflags) || (pfds[1].revents & errflags)) { + res = -1; + } else { + if ((pfds[0].revents & POLLIN)) { + *a=1; + res++; + } + if ((pfds[1].revents & POLLIN)) { + *b=1; + res++; + } + } + + if (res == 1) { + /* No event found what to do */ + res=-1; + } + } + + return res; +} +#endif + + +static struct media_session *media_session_new(struct woomera_interface *woomera) +{ + struct media_session *ms = NULL; + int x; + char *p; + int span,chan; + + span=woomera->span; + chan=woomera->chan; + + log_printf(2, server.log,"Starting new MEDIA session [%s] [%s]\n", + woomera->interface,woomera->raw?woomera->raw:"N/A"); + + if ((ms = malloc(sizeof(struct media_session)))) { + memset(ms, 0, sizeof(struct media_session)); + + if (woomera->loop_tdm != 1) { + for(x = 0; x < strlen(woomera->raw) ; x++) { + if (woomera->raw[x] == ':') { + break; + } + if (woomera->raw[x] == '/') { + break; + } + } + + ms->ip = strndup(woomera->raw, x); + time(&ms->started); + p = woomera->raw + (x+1); + ms->port = atoi(p); + } + + time(&ms->started); + woomera_set_ms(woomera,ms); + ms->woomera = woomera; + + /* Setup artificial DTMF stuff */ + memset(&ms->tone_session, 0, sizeof(ms->tone_session)); + if (teletone_init_session(&ms->tone_session, 0, NULL, NULL)) { + log_printf(0, server.log, "ERROR: Failed to initialize TONE [w%ig%i]!\n", + span+1,chan+1); + } + + ms->tone_session.rate = SMG_DTMF_RATE; + ms->tone_session.duration = server.dtmf_on * (ms->tone_session.rate / 1000); + ms->tone_session.wait = server.dtmf_off * (ms->tone_session.rate / 1000); + + teletone_dtmf_detect_init (&ms->dtmf_detect, SMG_DTMF_RATE); + + } else { + log_printf(0, server.log, "ERROR: Memory Alloc Failed [w%ig%i]!\n", + span+1,chan+1); + } + + return ms; +} + +static void media_session_free(struct media_session *ms) +{ + if (ms->ip) { + free(ms->ip); + } + + teletone_destroy_session(&ms->tone_session); + switch_buffer_destroy(&ms->dtmf_buffer); + + ms->woomera = NULL; + + free(ms); +} + + +static int create_udp_socket(struct media_session *ms, char *local_ip, int local_port, char *ip, int port) +{ + int rc; + struct hostent *result, *local_result; + char buf[512], local_buf[512]; + int err = 0; + + log_printf(5,server.log,"LocalIP %s:%d IP %s:%d \n",local_ip, local_port, ip, port); + + memset(&ms->remote_hp, 0, sizeof(ms->remote_hp)); + memset(&ms->local_hp, 0, sizeof(ms->local_hp)); + if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { + gethostbyname_r(ip, &ms->remote_hp, buf, sizeof(buf), &result, &err); + gethostbyname_r(local_ip, &ms->local_hp, local_buf, sizeof(local_buf), &local_result, &err); + if (result && local_result) { + ms->remote_addr.sin_family = ms->remote_hp.h_addrtype; + memcpy((char *) &ms->remote_addr.sin_addr.s_addr, ms->remote_hp.h_addr_list[0], ms->remote_hp.h_length); + ms->remote_addr.sin_port = htons(port); + + ms->local_addr.sin_family = ms->local_hp.h_addrtype; + memcpy((char *) &ms->local_addr.sin_addr.s_addr, ms->local_hp.h_addr_list[0], ms->local_hp.h_length); + ms->local_addr.sin_port = htons(local_port); + + rc = bind(ms->socket, (struct sockaddr *) &ms->local_addr, sizeof(ms->local_addr)); + if (rc < 0) { + close(ms->socket); + ms->socket = -1; + + log_printf(5,server.log, + "Failed to bind LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + + /* OK */ + + } else { + log_printf(0,server.log, + "Failed to get hostbyname LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + } else { + log_printf(0,server.log, + "Failed to create/allocate UDP socket\n"); + } + + return ms->socket; +} + +static int next_media_port(void) +{ + int port; + + pthread_mutex_lock(&server.media_udp_port_lock); + port = ++server.next_media_port; + if (port > WOOMERA_MAX_MEDIA_PORT) { + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + port = WOOMERA_MIN_MEDIA_PORT; + } + pthread_mutex_unlock(&server.media_udp_port_lock); + + return port; +} + + + +static int woomera_dtmf_transmit(struct media_session *ms, int mtu) +{ + struct woomera_interface *woomera = ms->woomera; + int bread; + unsigned char dtmf[1024]; + unsigned char dtmf_law[1024]; + sangoma_api_hdr_t hdrframe; + int i; + int slin_len = mtu*2; + short *data; + int used; + int res; + int err; + int txdtmf=0; + memset(&hdrframe,0,sizeof(hdrframe)); + + if (!ms->dtmf_buffer) { + return -1; + } + + for (;;) { + + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + break; + } + + res = waitfor_tx_socket(ms->sangoma_sock, -1, POLLERR | POLLOUT); + if (res <= 0) { + break; + } + +#ifdef CODEC_LAW_DEFAULT + + pthread_mutex_lock(&woomera->dtmf_lock); + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + pthread_mutex_unlock(&woomera->dtmf_lock); + break; + } + + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, slin_len); + pthread_mutex_unlock(&woomera->dtmf_lock); + + if (bread <= 0) { + break; + } + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes MTU=%i Coding=%i Used=%i\n", + woomera->interface,bread,mtu,ms->hw_coding,used); + + data=(short*)dtmf; + for (i=0;ihw_coding) { + /* ALAW */ + dtmf_law[i] = linear_to_alaw((int)data[i]); + } else { + /* ULAW */ + dtmf_law[i] = linear_to_ulaw((int)data[i]); + } + } + + err=sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf_law, mtu, 0); + + if (err != mtu) { + log_printf(0, woomera->log, "Error: Failed to TX to TDM API on DTMF (err=%i mtu=%i)!\n",err,mtu); + } + + txdtmf++; + ms->skip_write_frames++; +#else +... + pthread_mutex_lock(&woomera->dtmf_lock); + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, mtu); + pthread_mutex_unlock(&woomera->dtmf_lock); + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes\n", + woomera->interface,bread); + + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf, mtu, 0); + txdtmf++; + ms->skip_write_frames++; +#endif + + } + + if (txdtmf) { + return 0; + } else { + return -1; + } +} + +static void media_loop_run(struct media_session *ms) +{ + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int errs=0; + int res=0; + wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + char filename[100]; + FILE *filed=NULL; + int loops=0; + + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + + log_printf(1, server.log, "Media Loop Started %s fd=%i\n", + woomera->interface,ms->sangoma_sock); + + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "WANPIPE MEDIA Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + + + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } + + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + sangoma_tdm_disable_hwec(ms->sangoma_sock,&tdm_api); + + } + + if (errs) { + + log_printf(0, server.log, "Media Loop: failed to open tdm device %s\n", + woomera->interface); + return; + } + + if (server.loop_trace) { + sprintf(filename,"/smg/w%ig%i-loop.trace",woomera->span+1,woomera->chan+1); + unlink(filename); + filed = safe_fopen(filename, "w"); + } + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + ((res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2)) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + log_printf(0, server.log, "Media Loop Restart %s\n", + woomera->interface); + continue; + } + + if (res < 0 ){ + log_printf(0, server.log, "Media Loop Socket error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM Loop ReadMsg Error: %s\n", + strerror(errno), woomera->interface); + break; + } + + if (server.loop_trace && filed != NULL) { + int i; + for (i=0;isangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + res, 0); + + res=0; + + loops++; + } + + + if (res < 0) { + log_printf(2, server.log, "Media Loop: socket error %s (fd=%i)!\n", + woomera->interface, ms->sangoma_sock); + } + + + if (server.loop_trace && filed != NULL) { + fclose(filed); + } + + sangoma_tdm_enable_hwec(ms->sangoma_sock,&tdm_api); + + sleep(1); + + close_socket(&ms->sangoma_sock); + + log_printf(1, server.log, "Media Loop Finished %s Master=%i MediaEnd=%i Loops=%i\n", + woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_MEDIA_END),loops); + + return; + +} + +#ifdef WP_HPTDM_API +static int media_rx_ready(void *p, unsigned char *data, int len) +{ + struct media_session *ms = (struct media_session *)p; + + if (ms->udp_sock < 0) { + return -1; + } + + return sendto(ms->udp_sock, + data,len, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + +} +#endif + +static void *media_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int local_port, x = 0, errs = 0, res = 0, packet_len = 0; + //int udp_cnt=0; + struct woomera_event wevent; + wanpipe_tdm_api_t tdm_api; + FILE *tx_fd=NULL; + int sock_timeout=200; + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + !woomera->interface || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(2, server.log, + "MEDIA session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(ms); + pthread_exit(NULL); + return NULL; + } + + + log_printf(2, server.log, "MEDIA session for [%s] started (ptr=%p loop=%i)\n", + woomera->interface,woomera,woomera->loop_tdm); + + if (woomera->loop_tdm) { + media_loop_run(ms); + ms->udp_sock=-1; + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + goto media_thread_exit; + } + + for(x = 0; x < 1000 ; x++) { + local_port = next_media_port(); + if ((ms->udp_sock = create_udp_socket(ms, server.media_ip, local_port, ms->ip, ms->port)) > -1) { + break; + } + } + + if (ms->udp_sock < 0) { + log_printf(0, server.log, "UDP Socket Error (%s) [%s] LocalPort=%d\n", + strerror(errno), woomera->interface, local_port); + + errs++; + } else { + +#ifdef WP_HPTDM_API + hp_tdm_api_span_t *span=hptdmspan[woomera->span+1]; + if (!span || !span->init) { + errs++; + } else { + hp_tdm_api_usr_callback_t usr_callback; + memset(&usr_callback,0,sizeof(usr_callback)); + usr_callback.p = ms; + usr_callback.rx_avail = media_rx_ready; + if (span->open_chan(span, &usr_callback, &ms->tdmchan,woomera->chan+1)) { + errs++; + } + } +#else + if ((ms->sangoma_sock = sangoma_create_socket_by_name(woomera->interface, NULL)) < 0) { + log_printf(0, server.log, "WANPIPE Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + +# ifdef CODEC_LAW_DEFAULT + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } +# else + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_SLINEAR) < 0 ) { + errs++; + } +# endif + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + +# ifdef CODEC_LAW_DEFAULT +# ifdef LIBSANGOMA_GET_HWCODING + ms->hw_coding=sangoma_tdm_get_hw_coding(ms->sangoma_sock, &tdm_api); + if (ms->hw_coding < 0) { + errs++; + } +# else +# error "libsangoma missing hwcoding feature: not up to date!" +# endif +# endif + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + } +#endif + } + + + +#ifdef WP_HPTDM_API + /* No tdm thread */ +#else + if (!errs && + launch_media_tdm_thread(woomera)) { + errs++; + } +#endif + + if (!errs) { + + unsigned char udp_frame[4096]; + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(udp_frame,0,sizeof(udp_frame)); +#ifdef DOTRACE + int fdin, fdout; + char path_in[512], path_out[512]; +#endif + + + +#if 0 + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: %s%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + ms->hw_coding ?"ALAW":"ULAW", + WOOMERA_RECORD_SEPERATOR + ); +#else + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Unique-Call-Id: %s%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: PCM-16%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + WOOMERA_RECORD_SEPERATOR + ); +#endif + + + enqueue_event(woomera, &wevent, EVENT_FREE_DATA); + +#ifdef DOTRACE + sprintf(path_in, "/tmp/debug-in.%d.raw", tc); + sprintf(path_out, "/tmp/debug-out.%d.raw", tc++); + fdin = open(path_in, O_WRONLY | O_CREAT, O_TRUNC, 0600); + fdout = open(path_out, O_WRONLY | O_CREAT, O_TRUNC, 0600); +#endif + + if (server.out_tx_test) { + tx_fd=fopen("/smg/sound.raw","rb"); + if (!tx_fd){ + log_printf(0,server.log, "FAILED TO OPEN Sound file!\n"); + } + } + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + (res = waitfor_socket(ms->udp_sock, sock_timeout, POLLERR | POLLIN)) >= 0) { + + unsigned int fromlen = sizeof(struct sockaddr_in); + + + if (res == 0) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + + log_printf(4, server.log, "%s: UDP Sock Timeout !!!\n", + woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if ((packet_len = recvfrom(ms->udp_sock, udp_frame, sizeof(udp_frame), + MSG_DONTWAIT, (struct sockaddr *) &ms->local_addr, &fromlen)) < 1) { + log_printf(2, server.log, "UDP Recv Error: %s\n",strerror(errno)); + break; + } + +#if 0 + log_printf(6, server.log, "%s: UDP Receive %i !!!\n", + woomera->interface,packet_len); +#endif + + if (packet_len > 0) { + + if (packet_len != sangoma_frame_len && ms->udp_sync_cnt <= 5) { + /* Assume that we will always receive SLINEAR here */ + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, packet_len/codec_sample); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + log_printf(3, server.log, + "%s: UDP TDM Period ReSync to Len=%i %ims (udp=%i) \n", + woomera->interface,sangoma_frame_len, + sangoma_frame_len/codec_sample,packet_len); + + + if (++ms->udp_sync_cnt >= 6) { + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, 20); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + log_printf(0, server.log, + "%s: UDP TDM Period Force ReSync to 20ms \n", + woomera->interface); + } + + } + + if (!server.out_tx_test) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + /* For sanity sake if we are doing the out test + * dont take any chances force tx udp data */ + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + continue; + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + continue; + } + + } + + if (server.out_tx_test && tx_fd && + fread((void*)udp_frame, + sizeof(char), + packet_len,tx_fd) <= 0) { + + sangoma_get_full_cfg(ms->sangoma_sock,&tdm_api); + fclose(tx_fd); + tx_fd=NULL; + } + +#ifdef WP_HPTDM_API + if (ms->tdmchan->push) { + ms->tdmchan->push(ms->tdmchan,udp_frame,packet_len); + } +#else + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + udp_frame, + packet_len, 0); +#endif + + } + +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + udp_cnt++; + if (udp_cnt && udp_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA UDP TX RX CNT %i %i\n", + woomera->interface,udp_cnt,packet_len); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media Thread: socket error !\n"); + } + } + + + + new_woomera_event_printf(&wevent, + "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Start-Time: %ld%s" + "End-Time: %ld%s" + "Answer-Time: %ld%s" + "Call-ID: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + woomera->session, + WOOMERA_LINE_SEPERATOR, + + time(&ms->started), + WOOMERA_LINE_SEPERATOR, + + time(NULL), + WOOMERA_LINE_SEPERATOR, + + time(&ms->answered), + WOOMERA_LINE_SEPERATOR, + + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + +media_thread_exit: + + if (woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + usleep(1000); + sched_yield(); + } + } + + + close_socket(&ms->udp_sock); + close_socket(&ms->sangoma_sock); + + if (tx_fd){ + fclose(tx_fd); + tx_fd=NULL; + } + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + + woomera_set_ms(woomera,NULL); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + + media_session_free(ms); + + log_printf(2, server.log, "MEDIA session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + + pthread_exit(NULL); + return NULL; +} + + + + +static void *media_tdm_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int res = 0; + //int tdm_cnt=0; + //wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + sangoma_api_hdr_t hdrframe; + + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || !woomera->interface) { + log_printf(2, server.log, "MEDIA TDM session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + pthread_exit(NULL); + return NULL; + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] started (ptr=%p)\n", + woomera->interface,woomera); + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + (res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } else if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "Media TDM Restart Failed%s\n", + woomera->interface); + break; + } + log_printf(0, server.log, "Media TDM Restart %s\n", + woomera->interface); + continue; + } else if (res < 0) { + log_printf(0, server.log, "Media TDM Sangoma Socket Error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM ReadMsg Error: %s\n", strerror(errno)); + break; + } + + res = sendto(ms->udp_sock, + circuit_frame, + res, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + if (res < 0) { + log_printf(2, server.log, "UDP Sento Error: %s\n", strerror(errno)); + break; + } +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + tdm_cnt++; + if (tdm_cnt && tdm_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA TDM TX RX CNT %i %i\n", + woomera->interface,tdm_cnt,res); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media TDM Thread: socket error !\n"); + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + + pthread_exit(NULL); + return NULL; + +} + + +/* This function must be called with process_lock + * because it modifies shared process_table */ + +static int launch_media_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms; + + if ((ms = media_session_new(woomera))) { + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_RUNNING); + result = pthread_create(&ms->thread, &attr, media_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(woomera->ms); + + } + pthread_attr_destroy(&attr); + + } else { + log_printf(0, server.log, "Failed to start new media session\n"); + } + + return result; + +} + +static int launch_media_tdm_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms = woomera_get_ms(woomera); + + if (!ms) { + return result; + } + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + result = pthread_create(&ms->thread, &attr, media_tdm_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +static struct woomera_interface * launch_woomera_loop_thread(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + char callid[20]; + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + + if ((woomera = alloc_woomera())) { + + woomera->chan = event->chan; + woomera->span = event->span; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->loop_tdm=1; + + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + woomera_set_interface(woomera,callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = woomera; + pthread_mutex_unlock(&server.process_lock); + + if (launch_woomera_thread(woomera)) { + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + free(woomera); + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + return woomera; +} + +static int woomera_message_parse(struct woomera_interface *woomera, struct woomera_message *wmsg, int timeout) +{ + char *cur, *cr, *next = NULL, *eor = NULL; + char buf[2048]; + int res = 0, bytes = 0, sanity = 0; + struct timeval started, ended; + int elapsed, loops = 0; + int failto = 0; + int packet = 0; + + memset(wmsg, 0, sizeof(*wmsg)); + + if (woomera->socket < 0 ) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Invalid Socket! %d\n", + woomera->interface,woomera->socket); + return -1; + } + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP !\n", + woomera->interface); + return -1; + } + + gettimeofday(&started, NULL); + memset(buf, 0, sizeof(buf)); + + if (timeout < 0) { + timeout = abs(timeout); + failto = 1; + } else if (timeout == 0) { + timeout = -1; + } + + + while (!(eor = strstr(buf, WOOMERA_RECORD_SEPERATOR))) { + if (sanity > 1000) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Failed Sanity Check!\n[%s]\n\n", woomera->interface, buf); + return -1; + } + + if ((res = waitfor_socket(woomera->socket, 1000, POLLERR | POLLIN) > 0)) { + res = recv(woomera->socket, buf, sizeof(buf), MSG_PEEK); + + if (res > 1) { + packet++; + } + if (!strncmp(buf, WOOMERA_LINE_SEPERATOR, 2)) { + res = read(woomera->socket, buf, 2); + return 0; + } + if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + } else if (res < 0) { + log_printf(3, woomera->log, WOOMERA_DEBUG_PREFIX + "%s error during packet retry #%d\n", + woomera->interface, loops); + return res; + } else if (loops) { + ysleep(100000); + } + } + + gettimeofday(&ended, NULL); + elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000)); + + if (res < 0) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Bad RECV\n", + woomera->interface); + return res; + } else if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + } + + if (packet && loops > 150) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout waiting for packet.\n", + woomera->interface); + return -1; + } + + if (timeout > 0 && (elapsed > timeout)) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout [%d] reached\n", + woomera->interface, timeout); + return failto ? -1 : 0; + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)) { + /* BRB! we have an Event to deliver....*/ + return 0; + } + + /* what're we still doing here? */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + !woomera_test_flag(woomera, WFLAG_RUNNING)) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MASTER RUNNING or RUNNING!\n", woomera->interface); + return -1; + } + loops++; + } + + *eor = '\0'; + bytes = strlen(buf) + 4; + + memset(buf, 0, sizeof(buf)); + res = read(woomera->socket, buf, bytes); + next = buf; + + if (woomera->debug > 1) { + log_printf(3, woomera->log, "%s:WOOMERA RX MSG: %s\n",woomera->interface,buf); + + } + + while ((cur = next)) { + + if ((cr = strstr(cur, WOOMERA_LINE_SEPERATOR))) { + *cr = '\0'; + next = cr + (sizeof(WOOMERA_LINE_SEPERATOR) - 1); + if (!strcmp(next, WOOMERA_RECORD_SEPERATOR)) { + break; + } + } + if (!cur || !*cur) { + break; + } + + if (!wmsg->last) { + char *cmd, *id, *args; + woomera_set_flag(wmsg, MFLAG_EXISTS); + cmd = cur; + + if ((id = strchr(cmd, ' '))) { + *id = '\0'; + id++; + if ((args = strchr(id, ' '))) { + *args = '\0'; + args++; + strncpy(wmsg->command_args, args, sizeof(wmsg->command_args)-1); + } + strncpy(wmsg->callid, id, sizeof(wmsg->callid)-1); + } + + strncpy(wmsg->command, cmd, sizeof(wmsg->command)-1); + } else { + char *name, *val; + name = cur; + + if ((val = strchr(name, ':'))) { + *val = '\0'; + val++; + while (*val == ' ') { + *val = '\0'; + val++; + } + strncpy(wmsg->values[wmsg->last-1], val, WOOMERA_STRLEN); + } + strncpy(wmsg->names[wmsg->last-1], name, WOOMERA_STRLEN); + if (name && val && !strcasecmp(name, "content-type")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + if (name && val && !strcasecmp(name, "content-length")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + + + } + wmsg->last++; + } + + wmsg->last--; + + if (bytes && woomera_test_flag(wmsg, MFLAG_CONTENT)) { + read(woomera->socket, wmsg->body, + (bytes > sizeof(wmsg->body)) ? sizeof(wmsg->body) : bytes); + } + + return woomera_test_flag(wmsg, MFLAG_EXISTS); + +} + +static struct woomera_interface *pull_from_holding_tank(int index, int span , int chan) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + + /* Block this index until the call is completed */ + server.holding_tank[index] = &woomera_dead_dev; + + woomera->timeout = 0; + woomera->index = 0; + woomera->span=span; + woomera->chan=chan; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static void clear_from_holding_tank(int index, struct woomera_interface *woomera) +{ + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] == &woomera_dead_dev) { + server.holding_tank[index] = NULL; + } else if (woomera && server.holding_tank[index] == woomera) { + server.holding_tank[index] = NULL; + } else if (server.holding_tank[index]) { + log_printf(0, server.log, "Error: Holding tank index %i not cleared %p !\n", + index, server.holding_tank[index]); + } + pthread_mutex_unlock(&server.ht_lock); + + return; +} + +static struct woomera_interface *peek_from_holding_tank(int index) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static int add_to_holding_tank(struct woomera_interface *woomera) +{ + int next, i, found=0; + + pthread_mutex_lock(&server.ht_lock); + + for (i=0;i= CORE_TANK_LEN) { + next = server.holding_tank_index = 1; + } + + if (next == 0) { + log_printf(0, server.log, "\nCritical Error on TANK INDEX == 0\n"); + continue; + } + + if (server.holding_tank[next]) { + continue; + } + + found=1; + break; + } + + if (!found) { + /* This means all tank vales are busy + * should never happend */ + pthread_mutex_unlock(&server.ht_lock); + log_printf(0, server.log, "\nCritical Error failed to obtain a TANK INDEX\n"); + return 0; + } + + server.holding_tank[next] = woomera; + woomera->timeout = time(NULL) + 100; + + pthread_mutex_unlock(&server.ht_lock); + return next; +} + +static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, + struct woomera_message *wmsg, + int media, int answer, int accept) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + + log_printf(4, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + + if (woomera_test_flag(woomera, WFLAG_HANGUP) || + !woomera_test_flag(woomera, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END)) { + + log_printf(2, server.log, + "ERROR! call was cancelled MEDIA on HANGUP or MEDIA END!\n"); + + woomera->timeout=0; + return -1; + } + + log_printf(3, server.log,"WOOMERA: GOT %s EVENT: [%s] RAW=%s\n", + wmsg->command,wmsg->callid,raw); + + + if (raw && + woomera->raw == NULL && + !woomera_test_flag(woomera, WFLAG_RAW_MEDIA_STARTED)) { + + woomera_set_flag(woomera, WFLAG_RAW_MEDIA_STARTED); + + woomera_set_raw(woomera, raw); + + if (launch_media_thread(woomera)) { + struct woomera_event wevent; + + log_printf(4, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + woomera->timeout=0; + return -1; + } + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + + } else { + + if (accept) { + if (!autoacm) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + } + + if (answer) { + struct media_session *ms; + + pthread_mutex_lock(&woomera->ms_lock); + if ((ms=woomera->ms)) { + time(&woomera->ms->answered); + } + pthread_mutex_unlock(&woomera->ms_lock); + + if (ms) { + + if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_ANSWERED, + 0); + log_printf(2, server.log, + "Sent SIGBOOST_EVENT_CALL_ANSWERED [w%dg%d]\n", + woomera->span+1,woomera->chan+1); + } else { + struct woomera_event wevent; + log_printf(0, server.log, + "WOOMERA ANSWER: FAILED [%s] no Media \n", + wmsg->command,wmsg->callid); + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + woomera->timeout=0; + return -1; + } + } + } + + { + struct woomera_event wevent; + new_woomera_event_printf(&wevent, "200 %s OK%s" + "Unique-Call-Id: %s%s", + answer ? "ANSWER" : + accept ? "ACCEPT" : "MEDIA", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + + return 0; +} + +static int handle_woomera_call_start (struct woomera_interface *woomera, + struct woomera_message *wmsg) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + call_signal_event_t event; + char *calling = woomera_message_header(wmsg, "local-number"); +#ifdef SMG_CALLING_NAME + char *calling_name = woomera_message_header(wmsg, "local-name"); +#endif + char *presentation = woomera_message_header(wmsg, "Presentation"); + char *screening = woomera_message_header(wmsg, "Screening"); + char *rdnis = woomera_message_header(wmsg, "RDNIS"); + char *called = wmsg->callid; + char *grp = wmsg->callid; + char *p; + int cause = 34; + int tg = 0; + + if (smg_check_all_busy()) { + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, + "405 SMG Server All Ckt Busy!%s", WOOMERA_RECORD_SEPERATOR); + log_printf(3, woomera->log, "SMG Server Full %d (ckt busy cnt=%i)\n", + server.call_count, server.all_ckt_busy); + return -1; + } + + log_printf(2, woomera->log, "New Call %d/%d\n", server.call_count, server.max_calls); + + if ((p = strchr(called, '/'))) { + *p = '\0'; + called = p+1; + tg = atoi(grp+1) - 1; + if (tg < 0) { + tg=0; + } + } + + woomera->trunk_group=tg; + + if (raw) { + woomera_set_raw(woomera, raw); + } + + woomera->index = add_to_holding_tank(woomera); + if (woomera->index < 1) { + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, + "405 SMG Server All Tanks Busy!%s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0, woomera->log, "Error: Call Tank Full (Call Cnt=%i)\n", + server.call_count); + return -1; + } + + + woomera->index_hold = woomera->index; + + call_signal_call_init(&event, calling, called, woomera->index); + + if (presentation) { + event.calling_number_presentation = atoi(presentation); + } else { + event.calling_number_presentation = 0; + } + + if (screening) { + event.calling_number_screening_ind = atoi(screening); + } else { + event.calling_number_screening_ind = 0; + } + + if (rdnis && strlen(rdnis)) { + strncpy((char*)event.redirection_string,rdnis, + sizeof(event.redirection_string)-1); + log_printf(0,server.log,"RDNIS %s\n", rdnis); + + } + +#ifdef SMG_CALLING_NAME + if (calling_name) { + strncpy((char*)event.calling_name,calling_name, + sizeof(event.calling_name)-1); + } +#endif + + event.trunk_group = tg; + + + if (call_signal_connection_write(&server.mcon, &event) <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, + "405 SMG Signalling Contestion!%s", + WOOMERA_RECORD_SEPERATOR); + return -1; + } + + socket_printf(woomera->socket, "100 Trying%s", WOOMERA_RECORD_SEPERATOR); + + log_printf(2, server.log, "Call Called Event [Setup ID: %d] TG=%d\n", + woomera->index,tg); + + return 0; +} + + +static void interpret_command(struct woomera_interface *woomera, struct woomera_message *wmsg) +{ + int answer = 0, media = 0, accept=0; + char *unique_id; + int cause=0; + + + + if (!strcasecmp(wmsg->command, "call")) { + int err; + if (strlen(woomera->session) != 0) { + /* Call has already been placed */ + socket_printf(woomera->socket, "400 Error Call already in progress %s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0,server.log,"Woomera RX Call Even while call in progress!\n"); + return; + } + + err=handle_woomera_call_start(woomera,wmsg); + if (err) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + return; + + } else if (!strcasecmp(wmsg->command, "bye") || !strcasecmp(wmsg->command, "quit")) { + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + if (cause) { + log_printf(3, woomera->log, "Bye Cause Received: [%s]\n", cause); + } + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + log_printf(2, woomera->log, "WOOMERA CMD: Bye Received: [%s]\n", woomera->interface); + + woomera_clear_flag(woomera, WFLAG_RUNNING); + socket_printf(woomera->socket, "200 Connection closed%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + + } else if (!strcasecmp(wmsg->command, "listen")) { + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + socket_printf(woomera->socket, "405 Listener already started%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + } else { + char *event_string; + + woomera_set_flag(woomera, WFLAG_LISTENING); + add_listener(woomera); + + if (!strcmp(wmsg->callid,"MASTER")) { + woomera_set_flag(woomera, WFLAG_MASTER_DEV); + log_printf(0,woomera->log, "Starting MASTER Listen Device!\n"); + master_reset=0; + } + + + socket_printf(woomera->socket, "%s", + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "200 Listener enabled%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + if ((event_string = dequeue_event(&server.master_connection))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + event_string = NULL; + } + } + return; + + } else if ((media = !strcasecmp(wmsg->command, "debug"))) { + + int debug_level=atoi(wmsg->callid); + + if (debug_level < 10) { + server.debug=debug_level; + log_printf(0,server.log,"SMG Debugging set to %i (window=%i)\n",server.debug,server.mcon.txwindow); + } + + return; + } + + + unique_id = woomera_message_header(wmsg, "Unique-Call-Id"); + if (!unique_id) { + + cause=111; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "400 Woomera cmd without uniquie id%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2,server.log,"Woomera RX Event (%s) without unique id!\n",wmsg->command); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (strlen(woomera->session) == 0) { + struct woomera_interface *session_woomera=NULL; + char *session=NULL; + int span, chan; + char ifname[100]; + /* If session does not exist this is an incoming call */ + sscanf(unique_id, "w%dg%d", &span, &chan); + span--; + chan--; + + log_printf(3, woomera->log, + "WOOMERA Got CMD %s Span=%d Chan=%d from session %s\n", + wmsg->command,span,chan,unique_id); + + if (smg_validate_span_chan(span,chan) != 0) { + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Invalid span/chan in session%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2, woomera->log, + "WOOMERA Warning invalid span chan in session %s %s\n", + wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + pthread_mutex_lock(&server.process_lock); + session = server.process_table[span][chan].session; + session_woomera = server.process_table[span][chan].dev; + + if (session_woomera) { + pthread_mutex_unlock(&server.process_lock); + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Session not found%s" + WOOMERA_RECORD_SEPERATOR); + + + log_printf(0, woomera->log, "WOOMERA Error channel in use %s %s\n", + wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (!session || strlen(session) == 0 || + strncmp(session,unique_id,sizeof(woomera->session))){ + pthread_mutex_unlock(&server.process_lock); + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Invalid/Expired Session%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(3, woomera->log, + "WOOMERA Warning: Cmd=%s with invalid session %s (orig=%s)\n", + wmsg->command,unique_id,session?session:"N/A"); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + server.process_table[span][chan].dev=woomera; + strncpy(woomera->session,unique_id,sizeof(woomera->session)); + sprintf(ifname,"w%dg%d",span+1,chan+1); + woomera_set_interface(woomera, ifname); + + woomera->span=span; + woomera->chan=chan; + + pthread_mutex_unlock(&server.process_lock); + + + log_printf(3, woomera->log, "WOOMERA Got New If=%s Session %s\n", + woomera->interface, woomera->session); + + + } else if (strncmp(woomera->session,unique_id,sizeof(woomera->session))) { + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Session Mis-match%s" + WOOMERA_RECORD_SEPERATOR); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (!strcasecmp(wmsg->command, "dtmf")) { + + log_printf(3, woomera->log, "WOOMERA CMD: DTMF Received: [%s] Digit %s Body %s\n", + woomera->interface, wmsg->command_args, wmsg->body); + + wanpipe_send_dtmf(woomera,wmsg->body); + + socket_printf(woomera->socket, "200 DTMF OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "hangup")) { + + int chan = -1, span = -1; + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + span=woomera->span; + chan=woomera->chan; + + log_printf(3, woomera->log, "WOOMERA CMD: Hangup Received: [%s] MEDIA EXIST Cause=%s\n", + woomera->interface,cause); + + if (smg_validate_span_chan(span,chan) != 0) { + + socket_printf(woomera->socket, "405 No Such Channel%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + } + + + log_printf(2, woomera->log, "Hangup Received: [w%dg%d]\n", + span+1,chan+1); + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + + socket_printf(woomera->socket, "200 HANGUP OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "proceed")) { + + log_printf(3, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + socket_printf(woomera->socket, + "200 %s PROCEED OK%s" + "Unique-Call-Id: %s%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + } else if ((media = !strcasecmp(wmsg->command, "media")) || + (answer = !strcasecmp(wmsg->command, "answer")) || + (accept = !strcasecmp(wmsg->command, "accept"))) { + + handle_woomera_media_accept_answer(woomera, wmsg, media,answer,accept); + + + + } else { + log_printf(0, server.log,"WOOMERA INVALID EVENT: %s [%s] \n", + wmsg->command,wmsg->callid); + socket_printf(woomera->socket, "501 Command '%s' not implemented%s", + wmsg->command, WOOMERA_RECORD_SEPERATOR); + } +} + + +/* + EVENT INCOMING 1 + Remote-Address: 10.3.3.104 + Remote-Number: + Remote-Name: Anthony Minessale!8668630501 + Protocol: H.323 + User-Agent: Post Increment Woomera 1.0alpha1 (OpenH323 v1.17.2) 9/61 + H323-Call-Id: 887b1ff8-bb1f-da11-85c0-0007e98988c4 + Local-Number: 996 + Start-Time: Fri, 09 Sep 2005 12:25:14 -0400 + Local-Name: root +*/ + + +static void handle_call_answer(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int kill = 0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + pthread_mutex_unlock(&server.process_lock); + + if (woomera && woomera->raw) { + char callid[80]; + struct woomera_event wevent; + + if (woomera_test_flag(woomera, WFLAG_ANSWER)) { + log_printf(1, server.log, "Refusing to double-answer a call!\n"); + return; + } + + woomera_set_flag(woomera, WFLAG_ANSWER); + + if (woomera->span != event->span || woomera->chan != event->chan) { + log_printf(1, server.log, "Refusing to start media on a different channel from the one we agreed on.!\n"); + kill++; + return; + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to answer a dead call!\n"); + kill++; + } else { + int err; + err=0; + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + woomera_set_interface(woomera, callid); +#ifndef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + + kill++; + } +#endif + + if (!kill) { + new_woomera_event_printf(&wevent, "EVENT CONNECT w%dg%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + } + } else { + log_printf(1, server.log, "Answer requested on non-existant session. [w%dg%d]\n", + event->span+1, event->chan+1); + kill++; + } + + if (kill && woomera) { + woomera_set_flag(woomera,WFLAG_MEDIA_END); + } + +#if 0 + if (kill) { + call_signal_event_t oevent; + + if (woomera) { + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* Do not hangup if this call was already hungup */ + return; + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } +#endif + +} + +static void handle_call_start_ack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + struct woomera_event wevent; + int kill = 0; + + if ((woomera = peek_from_holding_tank(event->call_setup_id))) { + char callid[80]; + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to ack a dead call!\n"); + kill++; + } else { + int err, span, chan; + + pull_from_holding_tank(event->call_setup_id,event->span,event->chan); + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + + span = event->span; + chan = event->chan; + + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + woomera_set_interface(woomera, callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[span][chan].dev = woomera; + sprintf(woomera->session,"%s-%i-%i",callid,rand(),rand()); + sprintf(server.process_table[span][chan].session,"%s-%s", + callid,woomera->session); + pthread_mutex_unlock(&server.process_lock); + + + +#ifdef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + + +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id:%s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + kill++; + } +#endif + if (!kill) { + new_woomera_event_printf(&wevent, "201 Accepted%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + new_woomera_event_printf(&wevent, "EVENT PROCEED w%dg%d%s" + "Channel-Name: g%d/%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + log_printf(2, server.log, "Call Answered Event ID = %d Device = w%dg%d!\n", + event->call_setup_id,woomera->span+1,woomera->chan+1); + } + } + } else { + log_printf(1, server.log, + "Event (START ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id, event->call_setup_id,event->span+1, event->chan+1); + kill++; + } + + if (kill && woomera) { + woomera_set_flag(woomera,WFLAG_MEDIA_END); + } + +#if 0 + if (kill) { + call_signal_event_t oevent; + + if (woomera) { + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* Do not hangup if this call was already hungup */ + return; + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } +#endif + +} + +static void handle_call_start_nack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int span=-1, chan=-1; + int ack=0; + + /* Always ACK the incoming NACK + * Send out the NACK ACK before pulling the TANK, because + * if we send after the pull, the outgoing call could send + * a message to boost with the pulled TANK value before + * we send a NACK ACK */ + + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + + if (event->call_setup_id > 0) { + woomera=peek_from_holding_tank(event->call_setup_id); + } + + if (woomera) { + + struct woomera_event wevent; + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(0, server.log, "Event CALL START NACK on hungup call [%d]!\n", + event->call_setup_id); + ack++; + } else { + + woomera_set_cause_topbx(woomera,event->release_cause); + woomera_set_flag(woomera, (WFLAG_HANGUP|WFLAG_HANGUP_NACK_ACK)); + + new_woomera_event_printf(&wevent, "EVENT HANGUP w%dg%d%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + /* Do not ack here, let woomera thread ack it */ + ack=0; + } + + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + + if (woomera) { + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } else if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* At this point call is already hang up */ + woomera=NULL; + } else { + /* At this point call is already hang up */ + woomera=NULL; + } + } + + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + + log_printf(2, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + if (!woomera_test_flag(woomera,WFLAG_HANGUP)){ + woomera_set_cause_topbx(woomera,event->release_cause); + } + + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END|WFLAG_HANGUP_NACK_ACK)); + + /* Nack Ack will be sent by the woomera thread */ + ack=0; + } else { + /* Valid state when we are not in autoacm mode */ + ack++; + log_printf(3, server.log, "Event: NACK no woomera on span chan [w%dg%d]!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(0, server.log, + "Error: Start Nack Invalid State Should not happen [%d] [w%dg%d]!\n", + event->call_setup_id, event->span+1, event->chan+1); + ack++; + } + + + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { + log_printf(0, server.log, "WARNING: All ckt busy!\n"); + smg_all_ckt_busy(); + } + + +#warning "Ignoring CALL GAP" +#if 0 + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP) { + log_printf(0, server.log, "WARNING: Call Gapping Detected!\n"); + smg_all_ckt_gap(); + } +#endif + + if (ack) { + span=0; + chan=0; + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + + isup_exec_command(span, + chan, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + + if (!woomera) { + log_printf(2, server.log, "Event (NACK ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id,event->call_setup_id, event->span+1, event->chan+1); + } + } +} + +static void handle_call_loop_start(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + + pthread_mutex_unlock(&server.process_lock); + return; + + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + + woomera=launch_woomera_loop_thread(event); + if (woomera == NULL) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + } + + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + + return; +} + +static void handle_call_start(call_signal_event_t *event) +{ + struct woomera_event wevent; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(0, server.log, + "Sent (From Handle START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg%d]\n", + event->span+1, event->chan+1); + + pthread_mutex_unlock(&server.process_lock); + return; + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + + new_woomera_event_printf(&wevent, "EVENT INCOMING w%dg%d%s" + "Unique-Call-Id: %s%s" + "Remote-Number: %s%s" + "Remote-Name: %s%s" + "Protocol: SS7%s" + "User-Agent: sangoma_mgd%s" + "Local-Number: %s%s" + "Channel-Name: g%d/%d%s" + "Trunk-Group: %d%s" + "Presentation: %d%s" + "Screening: %d%s" + "RDNIS: %s%s" + , + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + session, + WOOMERA_LINE_SEPERATOR, + event->calling_number_digits, + WOOMERA_LINE_SEPERATOR, +#ifdef SMG_CALLING_NAME + event->calling_name, +#else + "", +#endif + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + event->called_number_digits, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + WOOMERA_LINE_SEPERATOR, + event->calling_number_presentation, + WOOMERA_LINE_SEPERATOR, + event->calling_number_screening_ind, + WOOMERA_LINE_SEPERATOR, + event->redirection_string, + WOOMERA_RECORD_SEPERATOR + ); + + if (enqueue_event_on_listeners(&wevent)) { + enqueue_event(&server.master_connection, &wevent, EVENT_KEEP_DATA); + } else { + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_BUSY); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + } + + log_printf(0, server.log, + "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } + + destroy_woomera_event_data(&wevent); + +} + +static void handle_gap_abate(call_signal_event_t *event) +{ + log_printf(0, server.log, "NOTICE: GAP Cleared!\n", + event->span+1, event->chan+1); + smg_clear_ckt_gap(); +} + +static void handle_restart_ack(call_signal_connection_t *mcon,call_signal_event_t *event) +{ + mcon->rxseq_reset =0; +} + +static void handle_call_stop(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + int ack=0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + if (woomera) { + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } else if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* At this point call is already hangup */ + woomera=NULL; + } else { + /* At this point call is already hangup */ + woomera=NULL; + } + } + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + + woomera_set_cause_topbx(woomera,event->release_cause); + + woomera_set_flag(woomera, + (WFLAG_MEDIA_END|WFLAG_HANGUP|WFLAG_HANGUP_ACK)); + + /* We have to close the socket because + At this point we are release span chan */ + + log_printf(3, server.log, "Event CALL STOP on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + } else { + ack++; + } + + + if (ack) { + /* At this point we have already sent our STOP so its safe to ACK */ + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + 0); + } + + if (!woomera){ + /* This is allowed on incoming call if remote app does not answer it */ + log_printf(3, server.log, "Event CALL STOP referrs to a non-existant session [w%dg%d]!\n", + event->span+1, event->chan+1); + } +} + +static void handle_heartbeat(call_signal_event_t *event) +{ + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + } else { + int err=call_signal_connection_write(&server.mcon, event); + if (err <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + } + } + return; +} + +static void handle_call_stop_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + log_printf(2, server.log, "Stop Ack on [w%dg%d] [Setup ID: %d] [%s]!\n", + event->span+1, event->chan+1, event->call_setup_id, + woomera->interface); + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + } else { + log_printf(2, server.log, "Event CALL_STOP_ACK(%d) referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->event_id, event->span+1, event->chan+1, event->call_setup_id); + } + + /* No need for us to do any thing here */ + return; +} + + +static void handle_call_start_nack_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + if ((woomera=pull_from_holding_tank(event->call_setup_id,-1,-1))) { + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + } else { + log_printf(0, server.log, + "Event NACK ACK [w%dg%d] with valid span/chan no dev!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(2, server.log, + "Event NACK ACK referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->span+1, event->chan+1, event->call_setup_id); + } + + if (event->call_setup_id > 0) { + clear_from_holding_tank(event->call_setup_id, NULL); + } + + /* No need for us to do any thing here */ + return; +} + +#if 0 +static void validate_number(unsigned char *s) +{ + unsigned char *p; + for (p = s; *p; p++) { + if (*p < 48 || *p > 57) { + log_printf(2, server.log, "Encountered a non-numeric character [%c]!\n", *p); + *p = '\0'; + break; + } + } +} +#endif + +static int parse_ss7_event(call_signal_connection_t *mcon, call_signal_event_t *event) +{ + int ret = 0; + +#if 0 + validate_number((unsigned char*)event->called_number_digits); + validate_number((unsigned char*)event->calling_number_digits); +#endif + +#if 1 + log_printf(2, server.log, + "RX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + event->release_cause, + event->call_setup_id, + event->fseqno, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A") + ); +#endif + +#if 0 + log_printf(2, server.log, "RX EVENT\n"); + log_printf(2, server.log, "===================================\n"); + log_printf(2, server.log, " rType: %s (%0x HEX)\n", + call_signal_event_id_name(event->event_id),event->event_id); + log_printf(2, server.log, " rSpan: [%d]\n",event->span+1); + log_printf(2, server.log, " rChan: [%d]\n",event->chan+1); + log_printf(2, server.log, " rCalledNum: %s\n", + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A")); + log_printf(2, server.log, " rCallingNum: %s\n", + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")); + log_printf(2, server.log, " rCause: %d\n",event->release_cause); + log_printf(2, server.log, " rInterface: [w%dg%d]\n",event->span+1,event->chan+1); + log_printf(2, server.log, " rEvent ID: [%d]\n",event->event_id); + log_printf(2, server.log, " rSetup ID: [%d]\n",event->call_setup_id); + log_printf(2, server.log, " rSeq: [%d]\n",event->fseqno); + log_printf(2, server.log, "===================================\n"); + +#endif + +#if 0 + log_printf(2, server.log, + "\nRX EVENT\n" + "===================================\n" + " rType: %s (%0x HEX)\n" + " rSpan: [%d]\n" + " rChan: [%d]\n" + " rCalledNum: %s\n" + " rCallingNum: %s\n" + " rCause: %s\n" + " rInterface : [w%dg%d]\n" + " rEvent ID : [%d]\n" + " rSetup ID: [%d]\n" + " rSeq: [%d]\n" + "===================================\n" + "\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"), + release_to_string(event->release_cause), + event->span+1, + event->chan+1, + event->event_id, + event->call_setup_id, + event->fseqno + ); +#endif + + + switch(event->event_id) { + + case SIGBOOST_EVENT_CALL_START: + handle_call_start(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_CALL_START_ACK: + handle_call_start_ack(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK: + handle_call_start_nack(event); + break; + case SIGBOOST_EVENT_CALL_ANSWERED: + handle_call_answer(event); + break; + case SIGBOOST_EVENT_HEARTBEAT: + handle_heartbeat(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK_ACK: + handle_call_start_nack_ack(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED_ACK: + handle_call_stop_ack(event); + break; + case SIGBOOST_EVENT_INSERT_CHECK_LOOP: + handle_call_loop_start(event); + break; + case SIGBOOST_EVENT_REMOVE_CHECK_LOOP: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: + handle_restart_ack(mcon,event); + break; + case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: + handle_gap_abate(event); + break; + default: + log_printf(0, server.log, "Warning no handler implemented for [%s]\n", + call_signal_event_id_name(event->event_id)); + break; + } + + return ret; +} + + +static void *monitor_thread_run(void *obj) +{ + int ss = 0; + int policy=0,priority=0; + char a=0,b=0; + call_signal_connection_t *mcon=&server.mcon; + call_signal_connection_t *mconp=&server.mconp; + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + + if (call_signal_connection_open(mcon, + mcon->cfg.local_ip, + mcon->cfg.local_port, + mcon->cfg.remote_ip, + mcon->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCON Socket [%d] %s\n", + mcon->socket,strerror(errno)); + exit(-1); + } + + if (call_signal_connection_open(mconp, + mconp->cfg.local_ip, + mconp->cfg.local_port, + mconp->cfg.remote_ip, + mconp->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCONP Socket [%d] %s\n", + mconp->socket,strerror(errno)); + exit(-1); + } + + mcon->log = server.log; + mconp->log = server.log; + + isup_exec_command(0, + 0, + -1, + SIGBOOST_EVENT_SYSTEM_RESTART, + 0); + + mcon->rxseq_reset=1; + + smg_get_current_priority(&policy,&priority); + + log_printf(1, server.log, "Open udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + log_printf(1, server.log, "Monitor Thread Started (%i:%i)\n",policy,priority); + + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { +#if 0 + ss = waitfor_socket(server.mcon.socket, 1000, POLLERR | POLLIN); +#else + ss = waitfor_2sockets(mcon->socket, + mconp->socket, + &a, &b, 1000); +#endif + + if (ss > 0) { + + call_signal_event_t *event=NULL; + int i=0; + + if (b) { +mcon_retry_priority: + if ((event = call_signal_connection_readp(mconp,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event P [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mconp,event); + if (++i < 10) { + goto mcon_retry_priority; + } + + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost P Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + i=0; + + if (a) { +mcon_retry: + if ((event = call_signal_connection_read(mcon,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mcon,event); + + if (++i < 50) { + goto mcon_retry; + } + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + } + + if (ss < 0){ + log_printf(0, server.log, "Thread Run: Select Socket Error!\n"); + break; + } + + } + + log_printf(1, server.log, "Close udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + call_signal_connection_close(&server.mcon); + call_signal_connection_close(&server.mconp); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + log_printf(0, server.log, "Monitor Thread Ended\n"); + + return NULL; +} + +static void woomera_loop_thread_run(struct woomera_interface *woomera) +{ + int err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log, "Failed to start loop media thread\n"); + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + return; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP)) { + + sleep(1); + continue; + + } + + woomera_clear_flag(woomera, WFLAG_RUNNING); + + log_printf(2, server.log, "Woomera Session: For Loop Test exiting %s\n",woomera->interface); + + + + return; +} + +static void *woomera_thread_run(void *obj) +{ + struct woomera_interface *woomera = obj; + struct woomera_message wmsg; + struct woomera_event wevent; + char *event_string; + int mwi; + int err; + int policy=0, priority=0; + int span = -1, chan = -1; + + woomera_message_init(&wmsg); + + //smg_get_current_priority(&policy,&priority); + + log_printf(2, server.log, "WOOMERA session started (ptr=%p : loop=%i)(%i:%i) Index=%i\n", + woomera,woomera->loop_tdm,policy,priority, woomera->index); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_mutex_init(&woomera->queue_lock, NULL); + pthread_mutex_init(&woomera->ms_lock, NULL); + pthread_mutex_init(&woomera->dtmf_lock, NULL); + pthread_mutex_init(&woomera->vlock, NULL); + pthread_mutex_init(&woomera->flags_lock, NULL); + + if (woomera->loop_tdm) { + woomera_loop_thread_run(woomera); + goto woomera_session_close; + } + + err=socket_printf(woomera->socket, + "EVENT HELLO Sangoma Media Gateway%s" + "Supported-Protocols: TDM%s" + "Version: %s%s" + "Remote-Address: %s%s" + "Remote-Port: %d%s" + "Raw-Format: %s%s", + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + SMG_VERSION, WOOMERA_LINE_SEPERATOR, + inet_ntoa(woomera->addr.sin_addr), WOOMERA_LINE_SEPERATOR, + ntohs(woomera->addr.sin_port), WOOMERA_LINE_SEPERATOR, + server.hw_coding?"ALAW":"ULAW", WOOMERA_RECORD_SEPERATOR + ); + + if (err) { + log_printf(0, server.log, "Woomera session socket failure! (ptr=%p)\n", + woomera); + woomera_clear_flag(woomera, WFLAG_RUNNING); + goto woomera_session_close; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + woomera_test_flag(woomera, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + !master_reset) { + + + mwi = woomera_message_parse(woomera, &wmsg, WOOMERA_HARD_TIMEOUT); + if (mwi >= 0) { + + if (mwi) { + interpret_command(woomera, &wmsg); + } else if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + if (socket_printf(woomera->socket, "%s", event_string)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + free(event_string); + log_printf(4, server.log, + "WOOMERA session (ptr=%p) print string error\n", + woomera); + break; + } + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + if (woomera->timeout > 0 && time(NULL) >= woomera->timeout) { + + /* Sent the hangup only after we sent a NACK */ + + log_printf(2, server.log, + "WOOMERA session (ptr=%p) Call Timedout ! [%s] (Timeout=%d)\n", + woomera,woomera->interface,woomera->timeout); + + /* Let the Index check below send a NACK */ + if (woomera->index) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + break; + } + + } else { + log_printf(3, server.log, "WOOMERA session (ptr=%p) [%s] READ MSG Error %i \n", + woomera,woomera->interface,mwi); + break; + } + + } + +woomera_session_close: + + log_printf(2, server.log, "WOOMERA session (ptr=%p) is dying [%s]: SR=%d WR=%d WF=0x%04X\n", + woomera,woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_RUNNING), + woomera->flags); + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + usleep(100); + sched_yield(); + } + } + + + /*********************************************** + * Identify the SPAN CHAN to be used below + ***********************************************/ + + chan = woomera->chan; + span = woomera->span; + + + if (!woomera_test_flag(woomera, WFLAG_HANGUP)) { + + /* The call was not HUNGUP. This is the last check, + If the call is valid, hungup the call if the call + was never up the keep going */ + + + if (smg_validate_span_chan(span,chan) == 0) { + + if (!woomera->index) { + + if (autoacm || woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + woomera->q931_rel_cause_tosig); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT); + + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } else { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + woomera->q931_rel_cause_tosig); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT); + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_START_NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } + } else { + log_printf(0, woomera->log, "Woomera Not Sent CALL STOPPED - Instead NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + + } + }else{ + /* This can happend if an outgoing call times out + or gets hungup before it gets acked. Its not a + failure */ + if (!woomera->index) { + + /* In this case we really failed to tx STOP */ + log_printf(0, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + + } + +woo_re_hangup: + + /* We must send a STOP ACK to boost telling it that we are done */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + + /* SMG received a HANGUP from boost. + We must now send back the ACK to the HANGUP. + Boost will not release channel until we + ACK the hangup */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Ack) to SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + }else{ + /* This should never happen! If it does + we broke protocol */ + log_printf(0, woomera->log, + "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_ACK); + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + + /* SMG received a NACK from boost during call startup. + We must now send back the ACK to the NACK. + Boost will not release channel until we + ACK the NACK */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Nack Ack) to SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + woomera->index=0; + + } else if (woomera->index) { + isup_exec_command(0, + 0, + woomera->index, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + woomera->index=0; + + } else { + log_printf(0, woomera->log, + "FAILED: Sent (Nack Ack) SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); + + } + + if (woomera->index) { + + int index = woomera->index; + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Timeout: %ld%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + woomera->timeout, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(18), + WOOMERA_LINE_SEPERATOR, + 18, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + + if (peek_from_holding_tank(index)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(0, + 0, + index, + SIGBOOST_EVENT_CALL_START_NACK, + 0); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT); + + log_printf(2, woomera->log, + "Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] .. WAITING FOR NACK ACK\n", + index); + } + + } + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent NACK to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //30sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] ... \n", + index); + } + + if (overall_cnt > 10) { //300sec timeotu + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + break; + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { + break; + } + + usleep(5000); + sched_yield(); + } + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", + index); + + } else { + log_printf(2, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", + index); + + } + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent HANGUP to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + log_printf(2, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //10sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i] ... \n", + woomera->interface,woomera->index_hold); + } + + if (overall_cnt > 10) { //100sec + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + server.process_table[span][chan].dev != woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + usleep(5000); + sched_yield(); + } + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + } else { + log_printf(2, woomera->log, + "Wait GOT STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + } + } + + /***************************************************** + * We must wait for WFLAG_WAIT_FOR_STOPPED_ACK here + * so that STOP_ACK can access the woomera + *****************************************************/ + + if (smg_validate_span_chan(span,chan) == 0) { + log_printf(2, woomera->log, + "WOOMERA Clearing Processs Table ... \n", + woomera->interface); + pthread_mutex_lock(&server.process_lock); + if (server.process_table[span][chan].dev == woomera){ + server.process_table[span][chan].dev = NULL; + memset(server.process_table[span][chan].session,0,SMG_SESSION_NAME_SZ); + } + pthread_mutex_unlock(&server.process_lock); + } + +#if 0 +//Used for testing + if (1) { + int chan = woomera->chan; + int span = woomera->span; + if (smg_validate_span_chan(span,chan) == 0) { + pthread_mutex_lock(&server.process_lock); + /* This is possible in case media thread dies on startup */ + + if (server.process_table[span][chan]){ + log_printf(0, server.log, + "Sanity Span Chan Still in use: [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + //server.process_table[span][chan] = NULL; + } + pthread_mutex_unlock(&server.process_lock); + } + } +#endif + + usleep(3000000); + + /* Sanity Check */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP ACK\n"); + goto woo_re_hangup; + } + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP NACK ACK\n"); + goto woo_re_hangup; + } + + /* This is where we actually pull the index + * out of the tank. We had to keep the tank + * value until the end of the call. Tank is only + * used on outgoing calls. */ + if (woomera->index_hold >= 1) { + clear_from_holding_tank(woomera->index_hold, woomera); + woomera->index_hold=0; + } + + log_printf(2, woomera->log, "Woomera Thread Finished %u\n", (unsigned long) woomera->thread); + close_socket(&woomera->socket); + woomera->socket=-1; + + /* delete queue */ + while ((event_string = dequeue_event(woomera))) { + free(event_string); + } + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + del_listener(woomera); + } + + log_printf(2, server.log, "WOOMERA session for [%s] stopped (ptr=%p)\n", + woomera->interface,woomera); + + if (woomera_test_flag(woomera, WFLAG_MASTER_DEV)) { + log_printf(0,server.log,"MASTER Thread Stopped (ptr=%p)\n",woomera); + master_reset=0; + } + + + pthread_mutex_destroy(&woomera->queue_lock); + pthread_mutex_destroy(&woomera->ms_lock); + pthread_mutex_destroy(&woomera->dtmf_lock); + pthread_mutex_destroy(&woomera->vlock); + pthread_mutex_destroy(&woomera->flags_lock); + woomera_set_raw(woomera, NULL); + woomera_set_interface(woomera, NULL); + + woomera_message_clear(&wmsg); + + free(woomera); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count--; + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_exit(NULL); + return NULL; +} + + +static int launch_woomera_thread(struct woomera_interface *woomera) +{ + int result = 0; + pthread_attr_t attr; + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_RUNNING); + result = pthread_create(&woomera->thread, &attr, woomera_thread_run, woomera); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! (%i) %s\n", + __FUNCTION__,result,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + +static int launch_monitor_thread(void) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 10; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + log_printf(0,server.log,"%s: Old Priority =%i res=%i \n",__FUNCTION__, + param.sched_priority,result); + + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + result = pthread_create(&server.monitor_thread, &attr, monitor_thread_run, NULL); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +#ifdef WP_HPTDM_API +static void *hp_tdmapi_span_run(void *obj) +{ + hp_tdm_api_span_t *span = obj; + int err; + + log_printf(0,server.log,"Starting %s span!\n",span->ifname); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + if (!span->run_span) { + break; + } + + err = span->run_span(span); + if (err) { + break; + } + + } + + if (span->close_span) { + span->close_span(span); + } + + sleep(3); + log_printf(0,server.log,"Stopping %s span!\n",span->ifname); + + pthread_exit(NULL); +} + + +static int launch_hptdm_api_span_thread(int span) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 5; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + result = pthread_create(&server.monitor_thread, &attr, hp_tdmapi_span_run, &hptdmspan[span]); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + } + pthread_attr_destroy(&attr); + + return result; +} +#endif + +static int configure_server(void) +{ + struct woomera_config cfg; + char *var, *val; + int cnt = 0; + + server.dtmf_intr_ch = -1; + + if (!woomera_open_file(&cfg, server.config_file)) { + log_printf(0, server.log, "open of %s failed\n", server.config_file); + return 0; + } + + while (woomera_next_pair(&cfg, &var, &val)) { + if (!strcasecmp(var, "boost_local_ip")) { + strncpy(server.mcon.cfg.local_ip, val, + sizeof(server.mcon.cfg.local_ip) -1); + strncpy(server.mconp.cfg.local_ip, val, + sizeof(server.mconp.cfg.local_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_local_port")) { + server.mcon.cfg.local_port = atoi(val); + server.mconp.cfg.local_port = + server.mcon.cfg.local_port+1; + cnt++; + } else if (!strcasecmp(var, "boost_remote_ip")) { + strncpy(server.mcon.cfg.remote_ip, val, + sizeof(server.mcon.cfg.remote_ip) -1); + strncpy(server.mconp.cfg.remote_ip, val, + sizeof(server.mconp.cfg.remote_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_remote_port")) { + server.mcon.cfg.remote_port = atoi(val); + server.mconp.cfg.remote_port = + server.mcon.cfg.remote_port+1; + cnt++; + } else if (!strcasecmp(var, "logfile_path")) { + if (!server.logfile_path) { + server.logfile_path = strdup(val); + } + } else if (!strcasecmp(var, "woomera_port")) { + server.port = atoi(val); + } else if (!strcasecmp(var, "debug_level")) { + server.debug = atoi(val); + } else if (!strcasecmp(var, "out_tx_test")) { + server.out_tx_test = atoi(val); + } else if (!strcasecmp(var, "loop_trace")) { + server.loop_trace = atoi(val); + } else if (!strcasecmp(var, "rxgain")) { + server.rxgain = atoi(val); + } else if (!strcasecmp(var, "txgain")) { + server.txgain = atoi(val); + } else if (!strcasecmp(var, "dtmf_on_duration")){ + server.dtmf_on = atoi(val); + } else if (!strcasecmp(var, "dtmf_off_duration")){ + server.dtmf_off = atoi(val); + } else if (!strcasecmp(var, "dtmf_inter_ch_duration")){ + server.dtmf_intr_ch = atoi(val); + } else if (!strcasecmp(var, "max_calls")) { + int max = atoi(val); + if (max > 0) { + server.max_calls = max; + } + } else if (!strcasecmp(var, "autoacm")) { + int max = atoi(val); + if (max >= 0) { + autoacm=max; + } + + } else if (!strcasecmp(var, "media_ip")) { + strncpy(server.media_ip, val, sizeof(server.media_ip) -1); + } else { + log_printf(0, server.log, "Invalid Option %s at line %d!\n", var, cfg.lineno); + } + } + + /* Post initialize */ + if (server.dtmf_on == 0){ + server.dtmf_on=SMG_DTMF_ON; + } + if (server.dtmf_off == 0) { + server.dtmf_off=SMG_DTMF_OFF; + } + if (server.dtmf_intr_ch == -1) { + server.dtmf_intr_ch = 0; + } + server.dtmf_size=(server.dtmf_on+server.dtmf_off)*10*2; + + log_printf(0,server.log, "DTMF On=%i Off=%i IntrCh=%i Size=%i\n", + server.dtmf_on,server.dtmf_off,server.dtmf_intr_ch,server.dtmf_size); + + woomera_close_file(&cfg); + return cnt == 4 ? 1 : 0; +} + + + +static int main_thread(void) +{ + + struct sockaddr_in sock_addr, client_addr; + struct woomera_interface *new_woomera; + int client_sock = -1, pid = 0; + unsigned int len = 0; + FILE *tmp; + + if ((server.master_connection.socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + log_printf(0, server.log, "socket() failed\n"); + return 1; + } + + memset(&sock_addr, 0, sizeof(sock_addr)); /* Zero out structure */ + sock_addr.sin_family = AF_INET; /* Internet address family */ + sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + sock_addr.sin_port = htons(server.port); /* Local port */ + + /* Bind to the local address */ + if (bind(server.master_connection.socket, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0) { + log_printf(0, server.log, "bind(%d) failed\n", server.port); + return 1; + } + + /* Mark the socket so it will listen for incoming connections */ + if (listen(server.master_connection.socket, MAXPENDING) < 0) { + log_printf(0, server.log, "listen() failed\n"); + return 1; + } + + if ((pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "pid %d already exists.\n", pid); + exit(0); + } + + if (!(tmp = safe_fopen(PIDFILE, "w"))) { + log_printf(0, stderr, "Error creating pidfile %s\n", PIDFILE); + return 1; + } else { + fprintf(tmp, "%d", getpid()); + fclose(tmp); + tmp = NULL; + } + + no_nagle(server.master_connection.socket); + +#if 0 + if (1) { + int span,chan; + call_signal_event_t event; +#if 0 + span=1; + chan=30; + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); +#else + for (span=0;span<8;span++) { + for (chan=0;chan<31;chan++) { + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); + } + } +#endif + } +#endif + +#ifdef WP_HPTDM_API + if (1) { + int span; + for (span=0;span<16;span++) { + hptdmspan[span] = sangoma_hptdm_api_span_init(span); + if (!hptdmspan[span]) { + break; + } else { + log_printf(0, server.log, "HP TDM API Span: %d configured...\n", + span); + launch_hptdm_api_span_thread(span); + } + } + } +#endif + + log_printf(1, server.log, "Main Process Started: Woomera Ready port: %d\n", server.port); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + /* Set the size of the in-out parameter */ + len = sizeof(client_addr); + + /* Wait for a client to connect */ + if ((client_sock = accept(server.master_connection.socket, (struct sockaddr *) &client_addr, &len)) < 0) { + log_printf(0, server.log, "accpet() failed\n"); + return 1; + } + + if ((new_woomera = new_woomera_interface(client_sock, &client_addr, len))) { + log_printf(2, server.log, "Starting Thread for New Connection %s:%d Sock=%d\n", + inet_ntoa(new_woomera->addr.sin_addr), + ntohs(new_woomera->addr.sin_port), + client_sock); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count++; + pthread_mutex_unlock(&server.thread_count_lock); + if (launch_woomera_thread(new_woomera)) { + socket_printf(new_woomera->socket, + "501 call was cancelled!%s", + WOOMERA_RECORD_SEPERATOR); + + close_socket(&new_woomera->socket); + new_woomera->socket=-1; + free(new_woomera); + } + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + } + } + + log_printf(1, server.log, "Main Process End\n"); + + return 0; +} + +static int do_ignore(int sig) +{ + return 0; +} + +static int do_shut(int sig) +{ + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + close_socket(&server.master_connection.socket); + log_printf(1, server.log, "Caught SIG %d, Closing Master Socket!\n", sig); + return 0; +} + +static int sangoma_tdm_init (int span) +{ +#ifdef LIBSANGOMA_GET_HWCODING + wanpipe_tdm_api_t tdm_api; + int fd=sangoma_open_tdmapi_span(span); + if (fd < 0 ){ + return -1; + } else { + server.hw_coding=sangoma_tdm_get_hw_coding(fd,&tdm_api); + close_socket(&fd); + } +#else +#error "libsangoma missing hwcoding feature: not up to date!" +#endif + return 0; +} + + +static int woomera_startup(int argc, char **argv) +{ + int x = 0, pid = 0, bg = 0; + char *cfg=NULL, *debug=NULL, *arg=NULL; + + while((arg = argv[x++])) { + + if (!strcasecmp(arg, "-hup")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGHUP); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-term") || !strcasecmp(arg, "--term")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGTERM); + unlink(PIDFILE); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-version")) { + fprintf(stdout, "\nSangoma Media Gateway: Version %s\n\n", SMG_VERSION); + exit(0); + + } else if (!strcasecmp(arg, "-help")) { + fprintf(stdout, "%s\n%s [-help] | [ -version] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(0); + } else if (!strcasecmp(arg, "-wipe")) { + unlink(PIDFILE); + } else if (!strcasecmp(arg, "-bg")) { + bg = 1; + + } else if (!strcasecmp(arg, "-g")) { + coredump = 1; + + } else if (!strcasecmp(arg, "-debug")) { + if (argv[x] && *(argv[x]) != '-') { + debug = argv[x++]; + } + } else if (!strcasecmp(arg, "-cfg")) { + if (argv[x] && *(argv[x]) != '-') { + cfg = argv[x++]; + } + } else if (!strcasecmp(arg, "-log")) { + if (argv[x] && *(argv[x]) != '-') { + server.logfile_path = strdup(argv[x++]); + } + } else if (*arg == '-') { + log_printf(0, stderr, "Unknown Option %s\n", arg); + fprintf(stdout, "%s\n%s [-help] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(1); + } + } + + if (1){ + int spn; + for (spn=1;spn<=WOOMERA_MAX_SPAN;spn++) { + if (sangoma_tdm_init(spn) == 0) { + break; + } + } + if (spn>WOOMERA_MAX_SPAN) { + printf("\nError: Failed to access a channel on spans 1-16\n"); + printf(" Please start Wanpipe TDM API drivers\n"); + return 0; + } + } + + if (bg && (pid = fork())) { + log_printf(0, stderr, "Backgrounding!\n"); + return 0; + } + + q931_cause_setup(); + + server.port = 42420; + server.debug = 0; + strcpy(server.media_ip, "127.0.0.1"); + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + server.log = stdout; + server.master_connection.socket = -1; + server.master_connection.event_queue = NULL; + server.config_file = cfg ? cfg : "/etc/sangoma_mgd.conf"; + pthread_mutex_init(&server.listen_lock, NULL); + pthread_mutex_init(&server.ht_lock, NULL); + pthread_mutex_init(&server.process_lock, NULL); + pthread_mutex_init(&server.media_udp_port_lock, NULL); + pthread_mutex_init(&server.thread_count_lock, NULL); + pthread_mutex_init(&server.master_connection.queue_lock, NULL); + pthread_mutex_init(&server.master_connection.flags_lock, NULL); + pthread_mutex_init(&server.mcon.lock, NULL); + server.master_connection.chan = -1; + server.master_connection.span = -1; + + if (!configure_server()) { + log_printf(0, server.log, "configuration failed!\n"); + return 0; + } + +#ifndef USE_SYSLOG + if (server.logfile_path) { + if (!(server.log = safe_fopen(server.logfile_path, "a"))) { + log_printf(0, stderr, "Error setting logfile %s!\n", server.logfile_path); + server.log = stderr; + return 0; + } + } +#endif + + + if (debug) { + server.debug = atoi(debug); + } + + if (coredump) { + struct rlimit l; + memset(&l, 0, sizeof(l)); + l.rlim_cur = RLIM_INFINITY; + l.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_CORE, &l)) { + log_printf(0, stderr, "Warning: Failed to disable core size limit: %s\n", + strerror(errno)); + } + } + +#ifdef __LINUX__ + if (geteuid() && coredump) { + if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { + log_printf(0, stderr, "Warning: Failed to disable core size limit for non-root: %s\n", + strerror(errno)); + } + } +#endif + + + + (void) signal(SIGINT,(void *) do_shut); + (void) signal(SIGPIPE,(void *) do_ignore); + (void) signal(SIGHUP,(void *) do_shut); + + + woomera_set_flag(&server.master_connection, WFLAG_RUNNING); + if (launch_monitor_thread()) { + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + return 0; + } + + fprintf(stderr, "%s", WELCOME_TEXT); + log_printf(0, stderr, "Woomera STARTUP Complete. [AutoACM=%i]\n",autoacm); + + return 1; +} + +static int woomera_shutdown(void) +{ + char *event_string; + int told = 0, loops = 0; + + close_socket(&server.master_connection.socket); + pthread_mutex_destroy(&server.listen_lock); + pthread_mutex_destroy(&server.ht_lock); + pthread_mutex_destroy(&server.process_lock); + pthread_mutex_destroy(&server.media_udp_port_lock); + pthread_mutex_destroy(&server.thread_count_lock); + pthread_mutex_destroy(&server.master_connection.queue_lock); + pthread_mutex_destroy(&server.master_connection.flags_lock); + pthread_mutex_destroy(&server.mcon.lock); + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + + + if (server.logfile_path) { + free(server.logfile_path); + server.logfile_path = NULL; + } + + /* delete queue */ + while ((event_string = dequeue_event(&server.master_connection))) { + free(event_string); + } + + while(server.thread_count > 0) { + loops++; + + if (loops % 1000 == 0) { + told = 0; + } + + if (loops > 10000) { + log_printf(0, server.log, "Red Alert! threads did not stop\n"); + assert(server.thread_count == 0); + } + + if (told != server.thread_count) { + log_printf(1, server.log, "Waiting For %d thread%s.\n", + server.thread_count, server.thread_count == 1 ? "" : "s"); + told = server.thread_count; + } + ysleep(10000); + } + unlink(PIDFILE); + log_printf(0, stderr, "Woomera SHUTDOWN Complete.\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + + mlockall(MCL_FUTURE); + + + server.hw_coding=0; + + openlog (ps_progname ,LOG_PID, LOG_LOCAL2); + + if (! (ret = woomera_startup(argc, argv))) { + exit(0); + } + ret = main_thread(); + + woomera_shutdown(); + + return ret; +} + +/** EMACS ** + * Local variables: + * mode: C + * c-basic-offset: 4 + * End: + */ + diff --git a/ssmg/sangoma_mgd.trunk/scripts/.svn/all-wcprops b/ssmg/sangoma_mgd.trunk/scripts/.svn/all-wcprops index d765bbc..71bc333 100644 --- a/ssmg/sangoma_mgd.trunk/scripts/.svn/all-wcprops +++ b/ssmg/sangoma_mgd.trunk/scripts/.svn/all-wcprops @@ -1,7 +1,7 @@ K 25 svn:wc:ra_dav:version-url V 42 -/svn/sangoma_mgd/!svn/ver/23/trunk/scripts +/svn/sangoma_mgd/!svn/ver/50/trunk/scripts END astxs K 25 @@ -24,6 +24,6 @@ END old_cleanup.sh K 25 svn:wc:ra_dav:version-url -V 56 -/svn/sangoma_mgd/!svn/ver/1/trunk/scripts/old_cleanup.sh +V 57 +/svn/sangoma_mgd/!svn/ver/47/trunk/scripts/old_cleanup.sh END diff --git a/ssmg/sangoma_mgd.trunk/scripts/.svn/entries b/ssmg/sangoma_mgd.trunk/scripts/.svn/entries index 90f5358..5d5b02a 100644 --- a/ssmg/sangoma_mgd.trunk/scripts/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/scripts/.svn/entries @@ -1,14 +1,14 @@ 8 dir -24 +58 https://www.sangomapbx.com:/svn/sangoma_mgd/trunk/scripts https://www.sangomapbx.com:/svn/sangoma_mgd -2007-10-02T17:11:50.536582Z -23 +2007-12-20T00:48:05.657582Z +50 ncorbic @@ -76,10 +76,10 @@ file -2007-09-21T20:55:40.000000Z -a3450602a7d9993f45e6f67b0058b8b1 -2007-09-21T20:53:51.260136Z -1 -root +2007-12-05T19:56:32.000000Z +5ba3b75a11fdad62aa7f42f8cce6d1fb +2007-12-03T20:52:43.030929Z +47 +ncorbic has-props diff --git a/ssmg/sangoma_mgd.trunk/scripts/.svn/text-base/old_cleanup.sh.svn-base b/ssmg/sangoma_mgd.trunk/scripts/.svn/text-base/old_cleanup.sh.svn-base index ce317e0..aba944f 100644 --- a/ssmg/sangoma_mgd.trunk/scripts/.svn/text-base/old_cleanup.sh.svn-base +++ b/ssmg/sangoma_mgd.trunk/scripts/.svn/text-base/old_cleanup.sh.svn-base @@ -9,3 +9,6 @@ fi if [ -e /usr/sbin/smgss7_init_ctrl ]; then rm -f /usr/sbin/smgss7_init_ctrl fi +if [ -e /etc/init.d/smgss7_ctrl ]; then + rm -f /etc/init.d/smgss7_ctrl +fi diff --git a/ssmg/sangoma_mgd.trunk/scripts/callgen/.svn/entries b/ssmg/sangoma_mgd.trunk/scripts/callgen/.svn/entries index bbd0354..65eb30b 100644 --- a/ssmg/sangoma_mgd.trunk/scripts/callgen/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/scripts/callgen/.svn/entries @@ -1,7 +1,7 @@ 8 dir -24 +58 https://www.sangomapbx.com:/svn/sangoma_mgd/trunk/scripts/callgen https://www.sangomapbx.com:/svn/sangoma_mgd diff --git a/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/all-wcprops b/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/all-wcprops index 218764e..2c433ad 100644 --- a/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/all-wcprops +++ b/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/all-wcprops @@ -1,11 +1,11 @@ K 25 svn:wc:ra_dav:version-url V 49 -/svn/sangoma_mgd/!svn/ver/23/trunk/scripts/init.d +/svn/sangoma_mgd/!svn/ver/50/trunk/scripts/init.d END smgss7_init_ctrl K 25 svn:wc:ra_dav:version-url V 66 -/svn/sangoma_mgd/!svn/ver/23/trunk/scripts/init.d/smgss7_init_ctrl +/svn/sangoma_mgd/!svn/ver/50/trunk/scripts/init.d/smgss7_init_ctrl END diff --git a/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/entries b/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/entries index ac34618..8f8082d 100644 --- a/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/entries @@ -1,14 +1,14 @@ 8 dir -24 +58 https://www.sangomapbx.com:/svn/sangoma_mgd/trunk/scripts/init.d https://www.sangomapbx.com:/svn/sangoma_mgd -2007-10-02T17:11:50.536582Z -23 +2007-12-20T00:48:05.657582Z +50 ncorbic @@ -32,10 +32,10 @@ file -2007-10-03T19:44:50.000000Z -9d70d87f6dfceaf193f93c047fc8d6df -2007-10-02T17:11:50.536582Z -23 +2007-12-20T17:31:41.000000Z +d66448101bb8d62f7c3723618b2619f8 +2007-12-20T00:48:05.657582Z +50 ncorbic has-props diff --git a/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/text-base/smgss7_init_ctrl.svn-base b/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/text-base/smgss7_init_ctrl.svn-base index 869eb29..6bf0313 100644 --- a/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/text-base/smgss7_init_ctrl.svn-base +++ b/ssmg/sangoma_mgd.trunk/scripts/init.d/.svn/text-base/smgss7_init_ctrl.svn-base @@ -8,6 +8,16 @@ ss7boost="ss7boost" #Set the ss7box file name ss7box="ss7boxd" +if [ -f /etc/wanpipe/pbxd ]; then + . /etc/wanpipe/pbxd +fi + +if [ "$PBXD" = "" ]; then + PBXD="asterisk" +fi + +PBXD_LAUNCH="safe_$PBXD" + smgctrl_log="/etc/wanpipe/smgctrl_log" ss7dir="/usr/local/ss7box" @@ -71,21 +81,28 @@ EOUT -function ast_ctrl () +function pbx_ctrl () { cmd=$1 cd $ss7dir if [ $cmd != "start" ]; then - echo "Stopping: asterisk" + echo "Stopping: $PBXD" + fi + eval "killall $PBXD_LAUNCH 2> /dev/null > /dev/null" + eval "killall $PBXD 2> /dev/null > /dev/null" + sleep 1 + eval "killall $PBXD 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + eval "killall -9 $PBXD_LAUNCH 2> /dev/null > /dev/null" + eval "killall -9 $PBXD 2> /dev/null > /dev/null" fi - eval "kill -TERM $(pidof asterisk) 2>> $smgctrl_log" if [ $cmd = "start" ]; then sleep 1 - echo "Starting: asterisk" - eval "asterisk -g >> $smgctrl_log" + echo "Starting: $PBXD" + eval "$PBXD_LAUNCH" fi cd $homedir @@ -192,11 +209,11 @@ case "$arg1" in if [ "$arg2" == isup ]; then ss7_boost_ctrl "$arg1" - ast_ctrl "$arg1" + pbx_ctrl "$arg1" else ss7_box_ctrl "$arg1" ss7_boost_ctrl "$arg1" - ast_ctrl "$arg1" + pbx_ctrl "$arg1" echo cat /proc/net/wanrouter/status @@ -207,10 +224,10 @@ case "$arg1" in stop) if [ "$arg2" == isup ]; then - ast_ctrl "$arg1" + pbx_ctrl "$arg1" ss7_boost_ctrl "$arg1" else - ast_ctrl "$arg1" + pbx_ctrl "$arg1" ss7_boost_ctrl "$arg1" ss7_box_ctrl "$arg1" diff --git a/ssmg/sangoma_mgd.trunk/scripts/init.d/smgss7_init_ctrl b/ssmg/sangoma_mgd.trunk/scripts/init.d/smgss7_init_ctrl index 869eb29..6bf0313 100755 --- a/ssmg/sangoma_mgd.trunk/scripts/init.d/smgss7_init_ctrl +++ b/ssmg/sangoma_mgd.trunk/scripts/init.d/smgss7_init_ctrl @@ -8,6 +8,16 @@ ss7boost="ss7boost" #Set the ss7box file name ss7box="ss7boxd" +if [ -f /etc/wanpipe/pbxd ]; then + . /etc/wanpipe/pbxd +fi + +if [ "$PBXD" = "" ]; then + PBXD="asterisk" +fi + +PBXD_LAUNCH="safe_$PBXD" + smgctrl_log="/etc/wanpipe/smgctrl_log" ss7dir="/usr/local/ss7box" @@ -71,21 +81,28 @@ EOUT -function ast_ctrl () +function pbx_ctrl () { cmd=$1 cd $ss7dir if [ $cmd != "start" ]; then - echo "Stopping: asterisk" + echo "Stopping: $PBXD" + fi + eval "killall $PBXD_LAUNCH 2> /dev/null > /dev/null" + eval "killall $PBXD 2> /dev/null > /dev/null" + sleep 1 + eval "killall $PBXD 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + eval "killall -9 $PBXD_LAUNCH 2> /dev/null > /dev/null" + eval "killall -9 $PBXD 2> /dev/null > /dev/null" fi - eval "kill -TERM $(pidof asterisk) 2>> $smgctrl_log" if [ $cmd = "start" ]; then sleep 1 - echo "Starting: asterisk" - eval "asterisk -g >> $smgctrl_log" + echo "Starting: $PBXD" + eval "$PBXD_LAUNCH" fi cd $homedir @@ -192,11 +209,11 @@ case "$arg1" in if [ "$arg2" == isup ]; then ss7_boost_ctrl "$arg1" - ast_ctrl "$arg1" + pbx_ctrl "$arg1" else ss7_box_ctrl "$arg1" ss7_boost_ctrl "$arg1" - ast_ctrl "$arg1" + pbx_ctrl "$arg1" echo cat /proc/net/wanrouter/status @@ -207,10 +224,10 @@ case "$arg1" in stop) if [ "$arg2" == isup ]; then - ast_ctrl "$arg1" + pbx_ctrl "$arg1" ss7_boost_ctrl "$arg1" else - ast_ctrl "$arg1" + pbx_ctrl "$arg1" ss7_boost_ctrl "$arg1" ss7_box_ctrl "$arg1" diff --git a/ssmg/sangoma_mgd.trunk/scripts/old_cleanup.sh b/ssmg/sangoma_mgd.trunk/scripts/old_cleanup.sh index ce317e0..aba944f 100755 --- a/ssmg/sangoma_mgd.trunk/scripts/old_cleanup.sh +++ b/ssmg/sangoma_mgd.trunk/scripts/old_cleanup.sh @@ -9,3 +9,6 @@ fi if [ -e /usr/sbin/smgss7_init_ctrl ]; then rm -f /usr/sbin/smgss7_init_ctrl fi +if [ -e /etc/init.d/smgss7_ctrl ]; then + rm -f /etc/init.d/smgss7_ctrl +fi diff --git a/ssmg/sangoma_mgd.trunk/sigboost.h b/ssmg/sangoma_mgd.trunk/sigboost.h index 5d64154..009e4b2 100644 --- a/ssmg/sangoma_mgd.trunk/sigboost.h +++ b/ssmg/sangoma_mgd.trunk/sigboost.h @@ -59,6 +59,7 @@ enum e_sigboost_call_setup_ack_nack_cause_values }; #define MAX_DIALED_DIGITS 31 +#define MAX_CALLING_NAME 31 /* Next two defines are used to create the range of values for call_setup_id * in the t_sigboost structure. diff --git a/ssmg/sangoma_mgd.trunk/smg_ctrl b/ssmg/sangoma_mgd.trunk/smg_ctrl index 01f181b..7f7d188 100755 --- a/ssmg/sangoma_mgd.trunk/smg_ctrl +++ b/ssmg/sangoma_mgd.trunk/smg_ctrl @@ -31,10 +31,8 @@ function stop_all() else echo "$sigd not running..." fi - if [ $(pidof $sigd) ]; then - echo "Error: failed to stop $sigd...exiting" - exit 1 - fi + + eval "kill -KILL $(pidof $sigd) 2>/dev/null >/dev/null" #stop sangoma media gateway if [ $(pidof sangoma_mgd) ]; then @@ -50,6 +48,8 @@ function stop_all() else echo "sangoma_mgd not running..." fi + + eval "kill -KILL $(pidof sangoma_mgd) 2>/dev/null >/dev/null" } function start_all() diff --git a/ssmg/sangoma_mgd.trunk/svn-commit.tmp b/ssmg/sangoma_mgd.trunk/svn-commit.tmp new file mode 100644 index 0000000..655b561 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/svn-commit.tmp @@ -0,0 +1,11 @@ +Nov 28 2007 + + * v1.22 Nenad Corbic + * Bug fix on socket open. Check for retun code >= 0 + * + +--This line, and those below, will be ignored-- + +M Changelog +M call_signal.c +M sangoma_mgd.c diff --git a/patches/kdrivers/src/net/.sdla_ppp.c.swp b/tmp/.diff.swp similarity index 51% rename from patches/kdrivers/src/net/.sdla_ppp.c.swp rename to tmp/.diff.swp index 52d4e41..6700131 100644 Binary files a/patches/kdrivers/src/net/.sdla_ppp.c.swp and b/tmp/.diff.swp differ diff --git a/tmp/Makefile b/tmp/Makefile new file mode 100644 index 0000000..c0ee6fd --- /dev/null +++ b/tmp/Makefile @@ -0,0 +1,254 @@ +# +# Makefile WANPIPE WAN Router Installation/Removal Makefile +# +# Copyright (c) 2007, Sangoma Technologies Inc. +# +# 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. +# ---------------------------------------------------------------------------- +# Author: Nenad Corbic +# + +PWD=$(shell pwd) +KBUILD_VERBOSE=0 + +#Default zaptel directory to be overwritten by user +ifndef ZAPDIR + ZAPDIR=/usr/src/zaptel +endif + +#Kernel version and location +ifndef KVER + KVER=$(shell uname -r) +endif +ifndef KMOD + KMOD=/lib/modules/$(KVER) +endif +ifndef KDIR + KDIR=$(KMOD)/build +endif +ifndef KINSTDIR + KINSTDIR=$(KMOD)/kernel +endif + +ifndef ARCH + ARCH=$(shell uname -m) +endif + +INSTALLPREFIX= + +#Local wanpipe includes +WINCLUDE=patches/kdrivers/include +HWECINC=patches/kdrivers/wanec/oct6100_api +KMODDIR=patches/kdrivers + +#Location of wanpipe source in release +WAN_DIR=$(PWD)/$(KMODDIR)/src/net +WANEC_DIR=$(PWD)/$(KMODDIR)/wanec +MODTYPE=ko +WANPIPE_ETC=/etc/wanpipe + +#Setup include path and extra cflags +EXTRA_CFLAGS := -I$(PWD)/$(WINCLUDE) -I$(PWD)/$(WINCLUDE)/annexg -I$(PWD)/patches/kdrivers/wanec -D__LINUX__ +EXTRA_CFLAGS += -I$(WANEC_DIR) -I$(WANEC_DIR)/oct6100_api -I$(WANEC_DIR)/oct6100_api/include +EXTRA_CFLAGS += -I$(KDIR)/include/linux -I$(ZAPDIR) + +#Setup utility extra flags and include path +EXTRA_UTIL_FLAGS = -I$(PWD)/$(WINCLUDE) -I$(KDIR)/include/ -I$(INSTALLPREFIX)/include -I$(INSTALLPREFIX)/usr/include +EXTRA_UTIL_FLAGS += -I$(PWD)/patches/kdrivers/wanec -I$(PWD)/patches/kdrivers/wanec/oct6100_api/include + +ENABLE_WANPIPEMON_ZAP=NO + +#Check if zaptel exists +ifneq (,$(wildcard $(ZAPDIR)/zaptel.h)) + ZAPDIR_PRIV=$(ZAPDIR) + ENABLE_WANPIPEMON_ZAP=YES + EXTRA_CFLGS+= -DSTANDALONE_ZAPATA -DBUILDING_TONEZONE + ZAP_OPTS= --zaptel-path=$(ZAPDIR) + ZAP_PROT=TDM +else + ZAP_OPTS= + ZAP_PROT= + ZAPDIR_PRIV= + ENABLE_WANPIPEMON_ZAP=NO +endif + +RM = @rm -rf +JUNK = *~ *.bak DEADJOE + + +# First pass, kernel Makefile reads module objects +ifneq ($(KERNELRELEASE),) +obj-m := sdladrv.o wanrouter.o wanpipe.o wanpipe_syncppp.o wanec.o + +# Second pass, the actual build. +else + +#This will check for zaptel, kenrel source and build utilites and kernel modules +#within local directory structure +all: _checkzap _checksrc all_util all_kmod + +#Build only kernel modules +all_kmod: _checkzap _checksrc _cleanoldwanpipe _check_kver + @if [ -e $(PWD)/ast_build_dir ]; then \ + rm -rf $(PWD)/ast_build_dir; \ + fi + @mkdir -p $(PWD)/ast_build_dir + ./Setup drivers --builddir=$(PWD)/ast_build_dir --with-linux=$(KDIR) $(ZAP_OPTS) --usr-cc=$(CC) --protocol=DEF-$(ZAP_PROT) --no-zaptel-compile --noautostart --silent + cp -f $(PWD)/ast_build_dir/lib/modules/$(KVER)/kernel/drivers/net/wan/* $(WAN_DIR)/ + cp -f $(PWD)/ast_build_dir/lib/modules/$(KVER)/kernel/net/wanrouter/* $(WAN_DIR)/ + + +#Clean utilites and kernel modules +clean: clean_util _cleanoldwanpipe + $(MAKE) -C $(KDIR) SUBDIRS=$(WAN_DIR) clean + @find patches/kdrivers -name '.*.cmd' | xargs rm -f + + +#Clean old wanpipe headers from linux include +_cleanoldwanpipe: _checksrc + @eval "./patches/build_links.sh" + @eval "./patches/clean_old_wanpipe.sh $(WINCLUDE) $(KDIR)/include/linux" + + +#Check for linux headers +_checksrc: + @if [ ! -e $(KDIR) ]; then \ + echo " Error linux headers/source not found: $(KDIR) !"; \ + echo ; \ + exit 1; \ + fi + @if [ ! -e $(KDIR)/.config ]; then \ + echo " Error linux headers/source not configured: missing $(KDIR)/.config !"; \ + echo ; \ + exit 1; \ + fi + @if [ ! -e $(KDIR)/include ]; then \ + echo " Error linux headers/source incomplete: missing $(KDIR)/include dir !"; \ + echo ; \ + exit 1; \ + fi + +_check_kver: + @eval "./patches/kern_i_private_check.sh $(KDIR)" + @echo > ./patches/kfeatures; + @if [ -e ./patches/i_private_found ]; then \ + echo "-DWANPIPE_USE_I_PRIVATE " >> ./patches/kfeatures; \ + fi + +#Check for zaptel +_checkzap: + @echo + @echo " +--------- Wanpipe Build Info --------------+" + @echo + @if [ ! -e $(ZAPDIR)/zaptel.h ]; then \ + echo " Compiling Wanpipe without ZAPTEL Support!"; \ + ZAPDIR_PRIV=; \ + ENABLE_WANPIPEMON_ZAP=NO; \ + else \ + echo " Compiling Wanpipe with ZAPTEL Support!"; \ + echo " Zaptel Dir: $(ZAPDIR)"; \ + echo; \ + eval "$(PWD)/patches/sangoma-zaptel-patch.sh $(ZAPDIR)"; \ + ZAPDIR_PRIV=$(ZAPDIR); \ + ENABLE_WANPIPEMON_ZAP=YES; \ + echo ; \ + echo "Please recompile and reinstall ZAPTEL after installation"; \ + fi + @echo + @echo " +-------------------------------------------+" + @echo + @sleep 2; + +#Install all utilities etc and modules +install: install_util install_etc install_kmod install_inc + +#Install kernel modules only +install_kmod: + @echo + @echo "Wanpipe kmod"; + @echo + install -m 644 -D $(WAN_DIR)/wanrouter.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanrouter.${MODTYPE} + install -m 644 -D $(WAN_DIR)/af_wanpipe.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/af_wanpipe.${MODTYPE} + install -m 644 -D $(WAN_DIR)/wanec.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanec.${MODTYPE} + install -m 644 -D $(WAN_DIR)/wan_aften.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wan_aften.${MODTYPE} + install -m 644 -D $(WAN_DIR)/sdladrv.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/sdladrv.${MODTYPE} + install -m 644 -D $(WAN_DIR)/wanpipe.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe.${MODTYPE} + @rm -f $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe_syncppp.${MODTYPE} + @if [ -f $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} ]; then \ + install -m 644 -D $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe_syncppp.${MODTYPE}; \ + fi + @rm -f $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanpipe_lip.${MODTYPE}; + @if [ -f $(WAN_DIR)/wanpipe_lip.${MODTYPE} ]; then \ + install -m 644 -D $(WAN_DIR)/wanpipe_lip.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanpipe_lip.${MODTYPE}; \ + fi + @eval "./patches/rundepmod.sh" + +endif + +#Compile utilities only +all_util: + $(MAKE) -C util all EXTRA_FLAGS="$(EXTRA_UTIL_FLAGS)" SYSINC="$(PWD)/$(WINCLUDE) -I $(PWD)/api/libsangoma/include" CC=$(CC) \ + PREFIX=$(INSTALLPREFIX) HOSTCFLAGS="$(EXTRA_UTIL_FLAGS)" ARCH=$(ARCH) + $(MAKE) -C util all_wancfg EXTRA_FLAGS="$(EXTRA_UTIL_FLAGS)" SYSINC="$(PWD)/$(WINCLUDE) -I$(PWD)/api/libsangoma/include" CC=$(CC) \ + PREFIX=$(INSTALLPREFIX) HOSTCFLAGS="$(EXTRA_UTIL_FLAGS)" HOSTCFLAGS="$(EXTRA_UTIL_FLAGS)" ARCH=$(ARCH) + +#Clean utilities only +clean_util: + $(MAKE) -C util clean SYSINC=$(PWD)/$(WINCLUDE) CC=$(CC) PREFIX=$(INSTALLPREFIX) + +#Install utilities only +install_util: + @echo + @echo "Install util"; + @echo + $(MAKE) -C util install SYSINC=$(PWD)/$(WINCLUDE) CC=$(CC) PREFIX=$(INSTALLPREFIX) + +#Install etc files +install_etc: + @echo + @echo "Wanpipe etc installing in $(INSTALLPREFIX)/$(WANPIPE_ETC)"; + @echo + @if [ ! -e $(INSTALLPREFIX)/$(WANPIPE_ETC) ]; then \ + mkdir -p $(INSTALLPREFIX)/$(WANPIPE_ETC); \ + fi + @if [ ! -e $(INSTALLPREFIX)/$(WANPIPE_ETC)/wanrouter.rc ]; then \ + install -D -m 644 samples/wanrouter.rc $(INSTALLPREFIX)/$(WANPIPE_ETC)/wanrouter.rc; \ + fi + @if [ ! -e $(INSTALLPREFIX)/$(WANPIPE_ETC)/lib ]; then \ + mkdir -p $(INSTALLPREFIX)/$(WANPIPE_ETC)/lib; \ + fi + @\cp -f util/wancfg_legacy/lib/* $(INSTALLPREFIX)/$(WANPIPE_ETC)/lib/ + @\cp -rf firmware $(INSTALLPREFIX)/$(WANPIPE_ETC)/ + @if [ ! -f $(INSTALLPREFIX)/$(WANPIPE_ETC)/interfaces ]; then \ + mkdir -p $(INSTALLPREFIX)/$(WANPIPE_ETC)/interfaces; \ + fi + @\cp -rf samples $(INSTALLPREFIX)/$(WANPIPE_ETC) + @if [ ! -d $(INSTALLPREFIX)/$(WANPIPE_ETC)/scripts ]; then \ + mkdir -p $(INSTALLPREFIX)/$(WANPIPE_ETC)/scripts; \ + fi + @\cp -rf wan_ec $(INSTALLPREFIX)/$(WANPIPE_ETC)/ + @install -D -m 755 samples/wanrouter $(INSTALLPREFIX)/usr/sbin/wanrouter + @echo + @echo "Wanpipe etc installed in $(INSTALLPREFIX)/$(WANPIPE_ETC)"; + @echo + +install_inc: + @echo + @echo "Install inc"; + @echo + @if [ -e $(INSTALLPREFIX)/usr/include/wanpipe ]; then \ + \rm -rf $(INSTALLPREFIX)/usr/include/wanpipe; \ + fi + @\mkdir -p $(INSTALLPREFIX)/usr/include/wanpipe + @\cp -f $(PWD)/patches/kdrivers/include/*.h $(INSTALLPREFIX)/usr/include/wanpipe/ + @\cp -rf $(PWD)/patches/kdrivers/wanec/oct6100_api/include/ $(INSTALLPREFIX)/usr/include/wanpipe/oct6100_api + @\cp -rf $(PWD)/patches/kdrivers/wanec/*.h $(INSTALLPREFIX)/usr/include/wanpipe/ + @echo + @echo "End of inc"; + @echo + + + diff --git a/tmp/Setup b/tmp/Setup new file mode 100755 index 0000000..c42c7e8 --- /dev/null +++ b/tmp/Setup @@ -0,0 +1,7138 @@ +#!/bin/sh +# +# Setup WANPIPE WAN Router Installation/Removal Script. +# +# Copyright (c) 1996-2007, Sangoma Technologies Inc. +# +# 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. +# ---------------------------------------------------------------------------- +# Nov 27, 2005 David Rokhvarg Added Echo Debugging option +# Mar 18, 2002 Nenad Corbic Added BSCSTRM protocol +# Mar 01, 2002 Nenad Corbic Added option to split rpm build into +# two packages: util and mod. +# Jan 05, 2002 Nenad Corbic Updated for 2.2.4 Release +# Mar 02, 2001 Nenad Corbic Added 2.4.2 kernel support +# Added a check for MODVERSIONS +# Feb 21, 2001 Nenad Corbic Fixed the kernel gcc compile bug. +# Feb 20, 2001 Nenad Corbic Fixed the kernel upgrade bug. +# Jan 31, 2001 Nenad Corbic Updated all help messages +# Added kernel upgrade feature +# Added WANPIPE driver compile feature +# Dec 25, 2000 Nenad Corbic Updated for v2.2.0 +# Feb 29, 2000 Nenad Corbic Removed print statements in file verification +# procedure. +# Oct 04, 1999 Nenad Corbic Updated for v2.1.0 +# Aug 26, 1999 Nenad Corbic Updated for v2.0.7 +# Aug 04, 1999 Nenad Corbic Updated for v2.0.5 +# Oct 13, 1998 Jaspreet Singh Updated for v2.0.4 +# Aug 31, 1998 Jaspreet Singh Updated for v2.0.3 +# Dev 09, 1997 Jaspreet Singh Updated for v2.0.2 +# Nov 28, 1997 Jaspreet Singh Updated for v2.0.1 +# Nov 06, 1997 Jaspreet Singh Updated for v2.0.0 +# Oct 16, 1997 Jaspreet Singh Added UID = 0 check +# Aug 26, 1997 Farhan Thawar Added patches.txt info +# Jul 28, 1997 Jaspreet Singh Updated for v1.0.5 +# Jul 10, 1997 Jaspreet Singh Updated for v1.0.4 +# Jan 15, 1997 Gene Kozin Added patch selection and upgrade features +# Dec 16, 1996 Gene Kozin Initial version based on Sangoma's WANPIPE(tm) +# ============================================================================ + +####### FUNCTION DEFINITIONS ################################################# + +# ---------------------------------------------------------------------------- +# Clear the screen if it is supported. +# ---------------------------------------------------------------------------- +clearscr() +{ + if test $NONINTERACTIVE; then + return + fi + + # check if the terminal environment is set up + [ "$TERM" ] && clear 2> /dev/null +} + +check_bash () +{ + BASH_SUPPORT=`echo $BASH_VERSION | cut -d'.' -f1 2> /dev/null` +} + +check_gcc () +{ + if [ "$USR_CC" != "" ]; then + eval "$USR_CC --version 2> /dev/null > /dev/null" + if [ $? -ne 0 ]; then + echo "Error: Failed to find version of $USR_CC" + return 1; + fi + eval "$USR_CC --version | grep \"^2\" > /dev/null" + if [ $? -eq 0 ]; then + GCC_VER=2; + else + GCC_VER=3; + fi + return 0; + fi + + GCC_VER=3 + + eval "gcc --version 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + CC=gcc + + + cd $DRIVER_UPDATE_DIR/src/net + eval "gcc --version | grep \"^2\" > /dev/null" + if [ $? -eq 0 ]; then + GCC_VER=2; + else + GCC_VER=3; + fi + + cd $PROD_HOME + return 0; + fi + + eval "cc --version 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + CC=cc + return 0; + fi + + return 1 +} + +check_awk () +{ + eval "type awk 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + AWK_SUPPORT=YES + else + AWK_SUPPORT=NO + fi +} +#fix for 2.6.18 kernels +check_inode_struct () +{ + if [ -e $SOURCEDIR/include/linux/fs.h ];then + eval "grep i_private $SOURCEDIR/include/linux/fs.h >/dev/null 2>/dev/null" + if [ $? -eq 0 ]; then + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DWANPIPE_USE_I_PRIVATE" + fi + fi +} + + + +# ---------------------------------------------------------------------------- +# Display error message. +# ---------------------------------------------------------------------------- +error() +{ + echo -e "Error: $*!" >&2 + return 0 +} + +# ---------------------------------------------------------------------------- +# Pause. +# ---------------------------------------------------------------------------- +pause() +{ + + local force_pause=$1 + + if [ -z $force_pause ]; then + if test $NONINTERACTIVE; then + return 0 + fi + else + shift + fi + + [ $# -ne 0 ] && echo -e $* >&2 + echo -e "Press [Enter] to continue...\c" >&2 + read tmp + return 0 +} + +# ---------------------------------------------------------------------------- +# Prompt user for input. +# ---------------------------------------------------------------------------- +prompt() +{ + if test $NONINTERACTIVE; then + return 0 + fi + + echo -ne "$*" >&2 + read CMD rest + return 0 +} + +# ---------------------------------------------------------------------------- +# Get Yes/No +# ---------------------------------------------------------------------------- +getyn() +{ + if test $NONINTERACTIVE; then + return 0 + fi + + while prompt "$* (y/n) " + do case $CMD in + [yY]) return 0 + ;; + [nN]) return 1 + ;; + *) echo -e "\nPlease answer y or n" >&2 + ;; + esac + done +} + +# ---------------------------------------------------------------------------- +# Select an item from the list. +# Return: 0 - selection is in $SEL +# 1 - quit or empty list +# ---------------------------------------------------------------------------- +get_select() +{ + [ $# -eq 0 ] && return 1 + + while prompt "Please enter your selection (1..$# or q) ->" + do case ${CMD:="0"} in + [0-9]|[0-9][0-9]) + [ $CMD -lt 1 -o $CMD -gt $# ] && continue + CMD=`expr $# - $CMD + 1 2>/dev/null` + until [ $# -eq $CMD ] + do shift + done + SEL=$1 + return 0 + ;; + q|Q) return 1 + ;; + esac + done +} + +# ---------------------------------------------------------------------------- +# Select an item from the list. +# Return: 0 - selection is in $SEL +# 1 - quit or empty list +# ---------------------------------------------------------------------------- +select_list() +{ + [ $# -eq 0 ] && return 1 + + col=`expr $# / 10 + 1` + cnt=0 + for option in $* + do cnt=`expr $cnt + 1` + echo -en "\t$cnt) $option" + [ `expr $cnt % $col` -eq 0 ] && echo "" + done + echo -e "\tq) quit\n" + get_select $* +} + +# ---------------------------------------------------------------------------- +# Parse product version. +# $1 product version X.Y.Z +# +# On exit, environment varibles are set as follows: +# MAJVER=X +# MINVER=Y +# SUBVER=Z +# ---------------------------------------------------------------------------- +parse_version() +{ + eval `echo $1 | awk ' + BEGIN { FS = "." } + NR == 1 { + printf " MAJVER=%s", $1; + printf " MINVER=%s", $2; + printf " SUBVER=%s", $3 + } + '` +} + +# ---------------------------------------------------------------------------- +# Display banner. +# ---------------------------------------------------------------------------- +banner() +{ + clearscr + echo -e "\t----------------------------------------------------------" + echo -e "\t WANPIPE v$PROD_VER Installation Script" + echo -e "\t Copyright (c) 1995-2007, Sangoma Technologies Inc." + echo -e "\t----------------------------------------------------------" + echo "" + return 0 +} + +# ---------------------------------------------------------------------------- +# Show welcome screen. +# ---------------------------------------------------------------------------- +welcome() +{ + banner + cat << ENDOFTEXT +${DISTR_NAME} INSTALLATION + +You are about to install ${DISTR_NAME} Multi-Protocol +Voice & WAN Router into your system. + +This script will examine your system, then install, create +and/or modify necessary files and directories. + +You must have Linux Kernel Headers along with +full development tools (i.e. GNU C compiler and utilities) +installed in order to be able to install this product. + +This script will automatically compile all WANPIPE kernel +drivers and install them in their appropriate directory. + +If you are installing Wanpipe for Asterisk/Zaptel this +script will will prompt you to re-install zaptel for you. + +If you have previoulsy installed WANPIPE, this release +will overrite/upgrade full release without the need to +uninstall first! + +IMPORTANT: +It is always recommended to say YES to all options +prompted during the install! + +Please visit: http://wiki.sangoma.com for more info. + +ENDOFTEXT + getyn "Would you like to install WANPIPE now? [y]" +} + +# ---------------------------------------------------------------------------- +# Goodbye. +# ---------------------------------------------------------------------------- +goodbye() +{ + banner + + if test "$DRIVERS_COMPILED" = yes; then + + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + + cat < /dev/null" + if [ $? -eq 0 ]; then + echo + echo "Warning: Wanpipe Modules are currently running!" + echo "Its recommended to unload Wanpipe Modules before proceeding" + echo "with installation." + echo + getyn "\nWould you like to proceed?" || return 1 + fi + missing_packages=" " + echo -n "Checking for C developement tools ..." + + check_gcc + if [ $? -eq 0 ]; then + echo "($CC) OK" + else + echo -e "\n\tWarning: Wanpipe package requires C development tools to complete + the installation. Please install development package + before proceeding. GCC/KGCC/CC compiler not found" + return 1 + fi + + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + pause + return 0 + fi + + echo -n "Checking for C++ developement tools ..." + eval "g++ --version > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "Failed!" + missing_packages=$missing_packages"g++ " + fi + echo -n "Checking for Make utility ..." + eval "make --version > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "Failed!" + missing_packages=$missing_packages"make " + fi + + echo -n "Checking for ncurses library ... " + if [ ! -f "/usr/include/ncurses.h" ] && [ ! -f "/usr/include/ncurses/ncurses.h" ]; then + echo "Failed!" + missing_packages=$missing_packages"ncurses " + else + echo "OK" + fi + + echo -n "Checking for Perl developement tools ..." + eval "perl --version 2>/dev/null > /dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "Failed!" + missing_packages=$missing_packages"perl " + fi + + echo -n "Checking for AWK ..." + eval "type awk 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "Failed!" + missing_packages=$missing_packages"awk " + fi + + echo -n "Checking for FLEX ..." + eval "type flex 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "Failed!" + missing_packages=$missing_packages"flex " + fi + + echo -n "Checking for Patch ..." + eval "patch --version 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "Failed!" + missing_packages=$missing_packages"patch " + fi + + echo -n "Checking for libtermcap-devel..." + if [ -f "/usr/include/termcap.h" ]; then + echo "OK" + else + "Failed!" + missing_packages=$missing_packages"libtermcap-devel " + fi + + echo -n "Checking for yacc..." + + echo -n "Checking for yacc..." + eval "type yacc 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "Failed!" + missing_packages=$missing_packages"yacc " + fi + + echo + if [ ! "$missing_packages" = " " ]; then + echo "WARNING: You are missing some prerequisites" + echo "Missing Packages $missing_packages" >> $CMP_LOG + for package in $missing_packages + do + case $package in + g++) + echo -e "\n C++ Compiler (g++)." + echo -e " Required for Wanpipe Utilities." + echo -e " Install gcc-c++ package (e.g yum install gcc-c++)." + ;; + make) + echo -e "\n make utility." + echo -e " Required for compiling packages." + echo -e " Install make package (e.g yum install make)." + ;; + + bash) + echo -e "\n Bash v2 or greater." + echo -e " Required for wancfg and cfgft1 configuration utilities." + ;; + ncurses) + echo -e "\n ncurses library." + echo -e " Required for wancfg and cfgft1 configuration utilities." + echo -e " Install ncurses development package (e.g yum install ncurses-devel)." + ;; + perl) + echo -e "\n Perl development tools." + echo -e " Required for Wanpipe package." + echo -e " Install ncurses Perl package (e.g yum install perl)." + ;; + awk) + echo -e "\n AWK." + echo -e " Required for wanrouter startup script." + echo -e " Install AWK package (e.g yum install gawk)." + ;; + patch) + echo -e "\n Patch ." + echo -e " Required for Wanpipe Setup installation script." + echo -e " Install Patch package (e.g yum install patch)." + ;; + libtermcap-devel) + echo -e "\n Libtermcap development tools ." + echo -e " Required for Wanpipe Utilities." + echo -e " Install libtermcap-devel package (e.g yum install libtermcap-devel)." + ;; + flex) + echo -e "\n Flex package ." + echo -e " Required for Wancfg configuration utility." + echo -e " Install flex package (e.g yum install flex)." + ;; + yacc) + echo -e "\n Yacc." + echo -e " Required for Wanpipe Utilities." + echo -e " Install byacc package (e.g yum install byacc)." + ;; + + esac + done + echo + getyn "Press Y to continue, N to abort installation" + if [ $? -eq 0 ]; then + return 0 + else + echo + echo "Stopping install per users request" + echo + return 1 + fi + fi + pause + + return 0 +} + + +# ---------------------------------------------------------------------------- +# Verify files and fix permissions. +# ---------------------------------------------------------------------------- +fix_perms() +{ + echo -n -e "\nVerifying files and fixing permissions ..." + + while read TYPE TARGET MODE OWNER GROUP rest + do + [ -z "$TARGET" ] && continue + [ -z "$MODE" -o -z "$OWNER" -o -z "$GROUP" ] && continue + + #Remove wanpipe/ directory from the + #target path, since we are in wanpipe + #directory :) + + TARGET=${TARGET#*/} + + case $TYPE in + d) + [ -d $TARGET ] || { + continue + } + ;; + f) + [ -f $TARGET ] || { + continue + } + ;; + *) continue + ;; + esac + + echo "chmod $MODE $TARGET" > /dev/null + chmod $MODE $TARGET + echo "chown $OWNER $TARGET" > /dev/null + chown $OWNER $TARGET + chgrp $GROUP $TARGET + #echo "Ok." + done < $FILELIST + echo "Done"; + return 0 +} + + + +apply_pre_211_fix () +{ + \cp -f $PROD_PATCH/$FIX_211 $SOURCEDIR + cd $SOURCEDIR + echo "Patching kernel lower than 2.2.11 !" + gzip -cd $FIX_211 | patch -p1 || { + getyn "\nWould you like to continue?" || return 1 + search_rej + rm $SOURCEDIR/$FIX_211 + return 0 + } + rm $SOURCEDIR/$FIX_211 +} + +update_wanpipe_drivers () +{ + local res=; + + echo + echo -n "Upgrading ${DISTR_NAME} kernel documentation ..." + cd $PROD_HOME + + + if [ "$PKG_NAME" != "wanpipe-lite" ]; then + if [ -d "$SOURCEDIR/Documentation" ]; then + eval "cp -f README $SOURCEDIR/Documentation/networking/wanpipe.txt" + eval "cp -f README $SOURCEDIR/Documentation/networking/wan-router.txt" + fi + fi + + echo -e "Done.\n" + + echo + echo -n "Upgrading ${DISTR_NAME} kernel headers ..." + + if [ ! -d $SOURCEDIR/include/linux ]; then + echo + echo "ERROR: Directory $SOURCEDIR/include/linux not found!" + echo " Corrupted linux headers in $SOURCEDIR dir." + echo + return 1 + fi + + cd $DRIVER_UPDATE_DIR/include/ + + if [ ! -e $WANPIPE_INCLUDE_DIR ]; then + eval "\mkdir -p $WANPIPE_INCLUDE_DIR" + fi + + if [ ! -e $WANPIPE_INCLUDE_DIR/linux ]; then + cd $WANPIPE_INCLUDE_DIR + ln -s . linux + cd $DRIVER_UPDATE_DIR/include/ + fi + + eval "\cp -f *.h $WANPIPE_INCLUDE_DIR/ 2> /dev/null" + + cd $DRIVER_UPDATE_DIR/wanec + eval "\cp -rf oct6100_api/include/ $WANPIPE_INCLUDE_DIR/oct6100_api 2> /dev/null" + eval "\cp -rf *.h $WANPIPE_INCLUDE_DIR/ 2> /dev/null" + eval "\cp -rf wanec_iface.h $SOURCEDIR/include/linux 2> /dev/null" + + cd $DRIVER_UPDATE_DIR/include/ + + if [ $superuser = "YES" ] && [ -e /usr/include/linux ]; then + eval "\cp -f *.h /usr/include/linux/ 2> /dev/null" + fi + + eval "\cp -f *.h $SOURCEDIR/include/linux/ 2> /dev/null" + if [ $? -eq 0 ]; then + echo -e "Done.\n" + else + echo -e "Failed!\n" + return 1 + fi + + + if [ -e $DRIVER_UPDATE_DIR/include/annexg ]; then + + cd $DRIVER_UPDATE_DIR/include/annexg + + if [ -e /usr/include/linux ]; then + eval "\cp -f *.h /usr/include/linux/ 2> /dev/null" + fi + + eval "\cp -f *.h $SOURCEDIR/include/linux/ 2> /dev/null" + fi + + cd $DRIVER_UPDATE_DIR/include/ + + + + echo -n "Upgrading ${DISTR_NAME} kernel drivers ..." + + if [ -d $SOURCEDIR/$LINUXDRIVERS_WAN ]; then + cd $DRIVER_UPDATE_DIR/src/wanrouter + + echo $PROD_VER > $SOURCEDIR/net/wanrouter/patchlevel + + eval "cp -f *.c $SOURCEDIR/$LINUXDRIVERS_WAN 2> /dev/null" + if [ $? -ne 0 ]; then + echo -e "Failed!\n" + return 1 + fi + fi + + if [ -d $SOURCEDIR/$LINUXDRIVERS_NET ]; then + cd $DRIVER_UPDATE_DIR/src/net + + eval "cp -f *.c $SOURCEDIR/$LINUXDRIVERS_NET 2> /dev/null" + if [ $? -eq 0 ]; then + echo -e "Done.\n" + else + echo -e "Failed!\n" + return 1 + fi + else + echo -e "Done.\n" + fi + + #The latest release 2.2.3 and above contain two extra files + #sdla_te1.c sdla_56k.c. The kernel make files must be updated + #when we perform the module updates. + + cd $SOURCEDIR + + if [ $KPATCH -eq 2 ]; then + + res=`grep sdla_56k.o drivers/net/Makefile` + if [ "$res" = "" ]; then + echo "Updating $SOURCEDIR/drivers/net/Makefile" + \cp -f $PROD_HOME/patches/$MAKE_PATCH_22X . + patch -p1 < $MAKE_PATCH_22X > /dev/null 2> /dev/null + \rm -f $MAKE_PATCH_22X + fi + + res=`grep wanpipe_utils.o drivers/net/Makefile` + if [ "$res" = "" ]; then + echo "Updating $SOURCEDIR/drivers/net/Makefile" + \cp -f $PROD_HOME/patches/$MAKE_UTILS_PATCH_22X . + patch -p1 < $MAKE_UTILS_PATCH_22X > /dev/null 2> /dev/null + rm -f $MAKE_UTILS_PATCH_22X + fi + + + elif [ $KPATCH -eq 4 ]; then + + ORIGMAKE="drivers/net/wan/Makefile" + NEWMAKE="drivers/net/wan/Makefile.nex" + + cp $ORIGMAKE $ORIGMAKE.orig + + res=`grep sdla_56k.o drivers/net/wan/Makefile` + if [ "$res" = "" ]; then + + echo "Updating T1/E1 in $SOURCEDIR/drivers/net/wan/Makefile" + + cat $ORIGMAKE | awk '{ gsub("sdla_ft1.o", "sdla_ft1.o sdla_56k.o sdla_te1.o ") ; print }' > $NEWMAKE + mv $NEWMAKE $ORIGMAKE + fi + + res=`grep wanpipe_utils.o drivers/net/wan/Makefile` + if [ "$res" = "" ]; then + + echo "Updating Utils in $SOURCEDIR/drivers/net/wan/Makefile" + + cat $ORIGMAKE | awk '{ gsub("sdla_ft1.o", "sdla_ft1.o wanpipe_utils.o ") ; print }' > $NEWMAKE + mv $NEWMAKE $ORIGMAKE + fi + + + res=`grep wanpipe_abstr.o drivers/net/wan/Makefile` + if [ "$res" = "" ]; then + + echo "Updating Abstr in $SOURCEDIR/drivers/net/wan/Makefile" + + cat $ORIGMAKE | awk '{ gsub("sdla_ft1.o", "sdla_ft1.o wanpipe_abstr.o ") ; print }' > $NEWMAKE + mv $NEWMAKE $ORIGMAKE + fi + + + res=`grep wanpipe_syncppp.o drivers/net/wan/Makefile` + if [ "$res" = "" ]; then + + echo "Updating Syncppp in $SOURCEDIR/drivers/net/wan/Makefile" + + cat $ORIGMAKE | awk '{ gsub("export-objs.*=\t", "export-objs =\twanpipe_syncppp.o ") ; print }' > $NEWMAKE + mv $NEWMAKE $ORIGMAKE + + fi + + res=`grep wanpipe_multppp.o drivers/net/wan/Makefile` + if [ $? -ne 0 ]; then + + echo "Updating MultPPP in $SOURCEDIR/drivers/net/wan/Makefile" + + cat $ORIGMAKE | awk '{ gsub("sdla_ppp.o", "sdla_ppp.o\nwanpipe-$(CONFIG_WANPIPE_MULTPPP) += wanpipe_multppp.o"); print }' > $NEWMAKE + mv $NEWMAKE $ORIGMAKE + fi + + + res=`grep sdla_mp_fr.o drivers/net/wan/Makefile` + if [ "$res" = "" ]; then + + echo "Updating MultFR in $SOURCEDIR/drivers/net/wan/Makefile" + + cat $ORIGMAKE | awk '{ gsub("wanpipe_multppp.o", "wanpipe_multppp.o\nwanpipe-$(CONFIG_WANPIPE_MULTFR) += sdla_mp_fr.o"); print }' > $NEWMAKE + + mv $NEWMAKE $ORIGMAKE + + fi + + rm -f $NEWMAKE + + + ORIGMAKE=net/wanrouter/Makefile + NEWMAKE=net/wanrouter/Makefile.nex + + cp $ORIGMAKE $ORIGMAKE.orig + + res=`grep af_wanpipe net/wanrouter/Makefile` + if [ "$res" = "" ]; then + + cat $ORIGMAKE | awk '{ gsub("obj-m.*:=", "obj-m := af_wanpipe.o"); print }' > $NEWMAKE + + mv $NEWMAKE $ORIGMAKE + + echo "Updating af_wanpipe in $SOURCEDIR/net/wanrouter/Makefile" + + fi + + res=`grep waniface.o net/wanrouter/Makefile` + if [ "$res" = "" ]; then + + cat $ORIGMAKE | awk '{ gsub("obj-y.*:=", "obj-y := waniface.o"); print }' > $NEWMAKE + mv $NEWMAKE $ORIGMAKE + + cat $ORIGMAKE | awk '{ gsub("export-objs.*:=", "export-objs := waniface.o"); print }' > $NEWMAKE + mv $NEWMAKE $ORIGMAKE + + echo "Updating Waniface in $SOURCEDIR/net/wanrouter/Makefile" + + fi + + + rm -f $NEWMAKE + + fi + + cd $PROD_HOME + return 0 +} + +get_kernel_ver () +{ + local tmp_ifs=$IFS + local err=0 + IFS="=" + + while read name value; + do + + if [ $AWK_SUPPORT = YES ]; then + name=`echo $name | awk '{ gsub(" ", "") ; print }'` + elif [ $BASH_SUPPORT -gt 1 ]; then + name=${name// /} + fi + + if [ $AWK_SUPPORT = YES ]; then + value=`echo $value | awk '{ gsub(" ", "") ; print }'` + elif [ $BASH_SUPPORT -gt 1 ]; then + value=${value// /} + fi + + case $name in + + VERSION) + KVER=$value + ;; + PATCHLEVEL) + KPATCH=$value + ;; + SUBLEVEL) + KLVL=$value + ;; + EXTRAVERSION) + KEVER=$value + break + ;; + esac + + done < $1/Makefile + + KERNEL_VERSION=$KVER"."$KPATCH"."$KLVL$KEVER + + if [ $KVER -eq 2 ] && [ $KPATCH -eq 6 ]; then + KERN_VER=26; + LINUXDRIVERS_NET="drivers/net/wan" + KLVL=${KLVL:-6} + elif [ $KVER -eq 2 ] && [ $KPATCH -eq 4 ]; then + KERN_VER=24; + LINUXDRIVERS_NET="drivers/net/wan" + elif [ $KVER -eq 2 ] && [ $KPATCH -eq 2 ]; then + KERN_VER=22; + LINUXDRIVERS_NET="drivers/net" + if [ $ADSL_PROT = YES ];then + echo "Warning: ADSL driver is only supported on 2.4.X & 2.6.X kernels!" + ADSL_PROT=NO + fi + fi + #It is possible that we couldn't find the kernel version from the Makefile + #Possible on SUSE kernels. + #Use the uname -r info obtained at the begining of the + #Setup sctipt. + + + IFS=$tmp_ifs + return $err +} + + +# ---------------------------------------------------------------------------- +# Apply kernel patches. +# ---------------------------------------------------------------------------- +apply_patches() +{ + local before_14 + local rc + + banner + cat << ENDOFTEXT + +Installing ${DISTR_NAME} Device Drivers: Linux KERNEL + +To integrate ${DISTR_NAME} Multi-Protocol Voice & WAN Router +modules into the Linux kernel, the kernel has to be +updated with latest wanpipe sources. Install will only +modify existing wanpipe source that is already in the +Kernel. + +IMPORTANT: +It is always recommended to say YES to all options +prompted during the install! + +ENDOFTEXT + + getyn "Would you like build wanpipe kernel drivers? [y]" || return 0 + + banner + + if [ $WITH_LINUX_OP = NO ]; then + echo -e "\nPlease specify absolute path name of your linux directory" + echo -e "\nPress Enter for Default: $SOURCEDIR\n" + echo -n "#>" + if test -z $NONINTERACTIVE; then + read response + + [ $response ] && { + SOURCEDIR=$response + } + fi + fi + + echo -e "Setting linux directory to $SOURCEDIR\n"; + INCLUDE=$SOURCEDIR/include/linux; + + + # Check kernel source directory + [ -d $SOURCEDIR ] || { + banner + cat << ENDOFTEXT +WARNING: Kernel source directory $SOURCEDIR not found! + +You may choose to continue installation and then apply patches after +you install kernel source. To apply patches after ${DISTR_NAME} installation +has been completed run './Setup drivers'. + +ENDOFTEXT + + getyn "Would you like to continue?" || return 1 + return 0 + } + cd $PROD_HOME/patches + + get_kernel_ver $SOURCEDIR + if [ $? -eq 1 ]; then + pause + return 1; + fi + + eval "echo "$SOURCEDIR/include" > $PROD_HOME/.sysinclude" + + #If the kernel has already been patched, offer an + #upgrade option. + check_kernel_patch_level $SOURCEDIR + #if [ $? -ne 0 ]; then + if [ 1 ]; then + echo + #echo "The kernel source in $SOURCEDIR has already been patched!" + #getyn "Would you like to upgrade ${DISTR_NAME} to the current version ?" || return 0 + + update_wanpipe_drivers + if [ $? -ne 0 ]; then + echo " +ERROR: Failed to upgrade ${DISTR_NAME} device drivers! + +Make sure that following directories exist: + '$SOURCEDIR/$LINUXDRIVERS_WAN' + '$SOURCEDIR/$LINUXDRIVERS_NET' + +Make sure that current kernel image version +matches the kernel version in $SOURCEDIR !!! + " + echo + getyn "Would you like to proceed ?" || return 1 + else + echo "${DISTR_NAME} device drivers upgraded successfully!" + fi + echo + pause + return 0; + fi + + cd $PROD_HOME/patches + + #-------- Pathching 2.0.X Kernels------------------------ + if [ $KPATCH -eq 0 ] + then + + cat < /dev/null + + pause + #search_rej + return 0 +} + +# ---------------------------------------------------------------------------- +# Install configuration files. +# ---------------------------------------------------------------------------- +install_config() +{ + banner + + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + + get_conf_dir + + cat << ENDOFTEXT +WANPIPE (LITE) CONFIGURATION + +Please read the wanpipe_lite_manual.(pdf/txt) manual for further +information. + +ENDOFTEXT + + else + + cat << ENDOFTEXT +WANPIPE META CONFIGURATION + +There are two configuration files associated with WANPIPE. + +1) $META_CONF: + - defines locations of important files such as lock + and configuration files as well as start/stop + order of multiple WANPIPE devices. +2) $PROD_CONF: + - main configuration file for each WANPIPE device. + - defines interfaces, hardware and protocol information. + - this file can be created using the 'wancfg' GUI + utility or manually based on sample files located + in /etc/wanpipe/samples. + +Please read the WanpipeInstallation.(pdf/txt) manual for further +information. + +ENDOFTEXT + pause + + # Create meta-configuration file. + create_mataconf + + fi + return 0 +} + + +function get_conf_dir () +{ + local response + + #banner + if test -z $NONINTERACTIVE; then + echo -e "\nPlease specify a desired location for ${DISTR_NAME} configuration files." + echo -e "\n\t(Press Enter for Default: /etc/wanpipe)\n" + echo -n "" + read response + + if [ $response ]; then + WAN_CONF_DIR=$response + else + WAN_CONF_DIR=/etc/wanpipe + fi + else + WAN_CONF_DIR=/etc/wanpipe + fi + + if [ ! -d $WAN_CONF_DIR ]; then + \mkdir -p $WAN_CONF_DIR + fi + + # Check kernel source directory + if [ ! -d $WAN_CONF_DIR ]; then + echo -e "\nERROR: Directory $WAN_CONF_DIR not found !\n" + getyn "Would you like to try again" + if [ $? -ne 0 ]; then + WAN_CONF_DIR=/etc/wanpipe + else + get_conf_dir + fi + fi +} + +function get_bin_dir () +{ + local response + + #banner + if test -z $NONINTERACTIVE; then + echo -e "\nPlease specify a location for WANPIPE binary, firmware files." + echo -e "\n\t(Press Enter for Default: /etc/wanpipe/firmware)\n" + echo -n "" + read response + + if [ $response ]; then + WAN_FIRMWARE_DIR=$response + else + WAN_FIRMWARE_DIR=/etc/wanpipe/firmware + fi + else + WAN_FIRMWARE_DIR=/etc/wanpipe/firmware + fi + + if [ ! -d $WAN_FIRMWARE_DIR ]; then + \mkdir -p $WAN_FIRMWARE_DIR + fi + + if [ ! -d $WAN_FIRMWARE_DIR ]; then + echo -e "\nERROR: Directory $WAN_FIRMWARE_DIR not found !\n" + getyn "Would you like to try again?" + if [ $? -ne 0 ]; then + WAN_FIRMWARE_DIR=/etc/wanpipe/firmware + else + get_bin_dir + fi + fi +} + + +function get_intr_dir () +{ + local response=no + local response1 + + WAN_INTR_DIR=/etc/wanpipe/interfaces + + if [ ! -d $WAN_INTR_DIR ]; then + \mkdir -p $WAN_INTR_DIR + fi + +# if [ -d "/etc/sysconfig/network-scripts" ]; then +# echo -e "\nWould you like to use the NEW network interface types?" +# echo "(RedHat feature:" +# echo " * Interface files will be written into" +# echo " /etc/sysconfig/network-scripts directory." +# echo " * Interface file names will start with ifcfg-" +# echo " * Enables the usage of ifup and ifdown scripts" +# echo -n "(y/n): " +# read response +# case $response in +# [yY]) WAN_INTR_DIR=/etc/sysconfig/network-scripts +# NEW_IF_TYPE=YES; +# response=yes +# ;; +# *) response=no +# ;; +# esac +# fi +# +# echo + + + if test -z $NONINTERACTIVE; then + if [ $response = no ]; then + + echo -e "\nPlease specify a desired location for WANPIPE interface files." + echo -e "\n\t(Press Enter for Default: $WAN_INTR_DIR)\n" + echo -n "" + read response1 + + WAN_INTR_DIR=/etc/wanpipe/interfaces + + if [ $response1 ]; then + WAN_INTR_DIR=$response1 + fi + fi + + echo + + # Check kernel source directory + if [ ! -d $WAN_INTR_DIR ]; then + echo -e "\nERROR: Directory $WAN_INTR_DIR not found !\n" + getyn "Would you like to try again?" + if [ $? -ne 0 ]; then + WAN_INTR_DIR=/etc/wanpipe/interfaces + else + get_intr_dir + fi + fi + fi + +} + +# ---------------------------------------------------------------------------- +# Create meta-configuration file. +# ---------------------------------------------------------------------------- +create_mataconf() +{ + local response + + # Select directory for the log file. + if [ -d /var/log ]; then + LOG_FILE=/var/log/$PROD + elif [ -d /var/adm wanpipe1]; then + LOG_FILE=/var/adm/$PROD + else + LOG_FILE=/etc/wanpipe/$PROD.log + fi + + # Select directory for the lock file. + if [ -d /var/lock/subsys ]; then + LOCK_FILE=/var/lock/subsys/$PROD + LOCK_DIR=/var/lock/subsys + elif [ -d /var/lock ]; then + LOCK_FILE=/var/lock/$PROD + LOCK_DIR=/var/lock + else + LOCK_FILE=/etc/wanpipe/$PROD.lck + LOCK_DIR=/etc/wanpipe + fi + + + if [ -f /etc/wanpipe/wanrouter.rc ]; then + . /etc/wanpipe/wanrouter.rc + fi + + if [ "$WAN_DEVICES" = "" ]; then + WAN_DEVICES="wanpipe1" + else + echo + echo "Wanpipe META config file found in /etc/wanpipe directory" + echo + echo "Wanpipe startup sequence: $WAN_DEVICES" + echo + getyn "Would you like to keep the original wanpipe startup sequence?" + if [ $? -ne 0 ]; then + echo + echo "New wanpipe startup sequence: wanpipe1" + WAN_DEVICES="wanpipe1" + fi + fi + + get_conf_dir + get_intr_dir + + get_bin_dir + + ENABLE_IP_FWD=NO + +# cat << EOF +# +#IP Forwarding enables/disables kernel packet routing. +# If this machine is a router select Y +# If this machine is a firewall select N +# +#Note: +# If ip forwarding is disabled the kernel will not +# route packets. Firewalling policy tables will have +# to be generaded first. +# +#Options: +#-------- +# Yes: Enable ip forwarding on router startup. +# No: Leave ip forwarding unchanged. +# +#EOF +# +# getyn "Enable IP Forwarding on Wanrouter Startup" +# if [ $? -ne 0 ]; then +# ENABLE_IP_FWD=NO +# else +# ENABLE_IP_FWD=YES +# fi +# + + if test $NONINTERACTIVE; then + ENABLE_IP_FWD=NO + fi + + if [ $ANNEXG_PROT = YES ]; then + ANNEXG_LOAD=YES; + fi + + cat > $META_CONF << ENDOFTEXT +#!/bin/sh +# router.rc WAN router meta-configuration file. +# +# This file defines variables used by the router shell scripts +# and should be located in /etc/wanpipe directory. These are: +# +# ROUTER_BOOT = Boot flag (YES/NO). +# WAN_CONF_DIR = Where to put wanpipe config files. +# WAN_INTR_DIR = Where to put wanpipe interface files. +# WAN_LOG = Where to put start-up log file. +# WAN_LOCK = File used as a lock. +# WAN_LOCK_DIR = +# WAN_IP_FORWARD = Enable IP Forwarding on startup. +# WAN_DEVICES = Name of the wanpipe devices to be +# loaded on 'wanrouter start' +# (ex: "wanpipe1 wanpipe2 wanpipe3...") +# +# Note: Name of wanpipe devices correspond +# to the configuration files in +# WANPIPE_CONF_DIR directory: +# (ex. $WAN_CONF_DIR/wanpipe1.conf ) +# +# Note: This file is 'executed' by the shell script, so +# the usual shell syntax must be observed. +ENDOFTEXT + + echo "ROUTER_BOOT=YES" >> $META_CONF + echo "WAN_CONF_DIR=$WAN_CONF_DIR" >> $META_CONF + echo "WAN_INTR_DIR=$WAN_INTR_DIR" >> $META_CONF + echo "WAN_BIN_DIR=/usr/sbin" >> $META_CONF + echo "WAN_LOG=$LOG_FILE" >> $META_CONF + echo "WAN_LOCK=$LOCK_FILE" >> $META_CONF + echo "WAN_LOCK_DIR=$LOCK_DIR" >> $META_CONF + echo "WAN_IP_FORWARD=$ENABLE_IP_FWD" >> $META_CONF + echo "NEW_IF_TYPE=$NEW_IF_TYPE" >> $META_CONF + echo "WAN_LIB_DIR=/etc/wanpipe/lib" >> $META_CONF + echo "WAN_ADSL_LIST=/etc/wanpipe/wan_adsl.list" >> $META_CONF + echo "WAN_ANNEXG_LOAD=$ANNEXG_LOAD" >> $META_CONF + echo "WAN_SCTP_LOAD=$SCTP_LOAD" >> $META_CONF + echo "WAN_LIP_LOAD=$LIP_LOAD" >> $META_CONF + echo "WAN_DYN_WANCONFIG=NO" >> $META_CONF + echo "WAN_SCRIPTS_DIR=/etc/wanpipe/scripts" >> $META_CONF + echo "WAN_FIRMWARE_DIR=$WAN_FIRMWARE_DIR" >> $META_CONF + echo "WAN_DEVICES_REV_STOP_ORDER=YES" >> $META_CONF + echo "WAN_DEVICES=\"$WAN_DEVICES\"" >> $META_CONF + + return 0 +} + +# ---------------------------------------------------------------------------- +# Install initialization scripts. +# ---------------------------------------------------------------------------- +install_init() +{ + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + return 0 + fi + + if [ $NO_AUTO_START -eq 1 ]; then + return 0; + fi + + + # Examine system bootstrap files. + if [ -d /etc/rc0.d ] + then RC_DIR=/etc + elif [ -d /etc/rc.d/rc0.d ] + then RC_DIR=/etc/rc.d + else return 0 + fi + + eval "find $RC_DIR -name 'S*wanrouter' | xargs rm 2> /dev/null" + eval "find $RC_DIR -name 'K*wanrouter' | xargs rm 2> /dev/null" + + banner + cat << ENDOFTEXT + +WANPIPE BOOTSTRAP CONFIGURATION + +Your system uses System V -style initialization scripts. You have an option +to add router start-up script to those scripts so that the router will start +automatically when system enters multi-user mode and shut down when it enters +single-user mode or when it is halted. + +i.e. By selecting this option WANPIPE will startup on system bootup and + stop on system shutdown. + +ENDOFTEXT + + getyn "Would you like to install WANPIPE start-up scripts?" || return 0 + + PROD_INIT=$PROD_INIT$PROD + echo -e "\n\t WANPIPE Setup for boot startup " + + if test -z $ROOT; then + # Install start scripts. + [ -d $RC_DIR/rc2.d ] && ln -sf $PROD_INIT $RC_DIR/rc2.d/$START_SCRIPT + [ -d $RC_DIR/rc3.d ] && ln -sf $PROD_INIT $RC_DIR/rc3.d/$START_SCRIPT + [ -d $RC_DIR/rc4.d ] && ln -sf $PROD_INIT $RC_DIR/rc4.d/$START_SCRIPT + [ -d $RC_DIR/rc5.d ] && ln -sf $PROD_INIT $RC_DIR/rc5.d/$START_SCRIPT + + # Install stop scripts. + [ -d $RC_DIR/rc0.d ] && ln -sf $PROD_INIT $RC_DIR/rc0.d/$STOP_SCRIPT + [ -d $RC_DIR/rc1.d ] && ln -sf $PROD_INIT $RC_DIR/rc1.d/$STOP_SCRIPT + [ -d $RC_DIR/rc6.d ] && ln -sf $PROD_INIT $RC_DIR/rc6.d/$STOP_SCRIPT + [ -d $RC_DIR/init.d ] && ln -sf $PROD_INIT $RC_DIR/init.d/$PROD + else + # Install start scripts. + [ -d $RC_DIR/rc2.d ] && install -D -m 755 $WANROUTER_STARTUP_SMPL $ROOT/$RC_DIR/rc2.d/$START_SCRIPT + [ -d $RC_DIR/rc3.d ] && install -D -m 755 $WANROUTER_STARTUP_SMPL $ROOT/$RC_DIR/rc3.d/$START_SCRIPT + [ -d $RC_DIR/rc4.d ] && install -D -m 755 $WANROUTER_STARTUP_SMPL $ROOT/$RC_DIR/rc4.d/$START_SCRIPT + [ -d $RC_DIR/rc5.d ] && install -D -m 755 $WANROUTER_STARTUP_SMPL $ROOT/$RC_DIR/rc5.d/$START_SCRIPT + + # Install stop scripts. + [ -d $RC_DIR/rc0.d ] && install -D -m 755 $WANROUTER_STARTUP_SMPL $ROOT/$RC_DIR/rc0.d/$STOP_SCRIPT + [ -d $RC_DIR/rc1.d ] && install -D -m 755 $WANROUTER_STARTUP_SMPL $ROOT/$RC_DIR/rc1.d/$STOP_SCRIPT + [ -d $RC_DIR/rc6.d ] && install -D -m 755 $WANROUTER_STARTUP_SMPL $ROOT/$RC_DIR/rc6.d/$STOP_SCRIPT + [ -d $RC_DIR/init.d ] && install -D -m 755 $WANROUTER_STARTUP_SMPL $ROOT/$RC_DIR/init.d/$PROD + fi + + if [ "$TDM_PROT" = "YES" ]; then + getyn "Would you like to auto-execute ztcfg after wanrouter start?" || return 0 + if [ ! -d $WAN_CONF_DIR/scripts ]; then + eval "\mkdir -p $WAN_CONF_DIR/scripts >/dev/null 2>/dev/null" + fi + eval "\cp -f $PROD_HOME/samples/wanpipe_zaptel_start $WAN_CONF_DIR/scripts/start >/dev/null 2>/dev/null" + if [ ! -f $WAN_CONF_DIR/scripts/start ]; then + echo "Error: Could not copy auto-ztcfg script" + fi + fi + pause + return 0 + +} + +# ---------------------------------------------------------------------------- +# Remove product. +# ---------------------------------------------------------------------------- +remove() +{ + banner + echo "You are about to uninstall WANPIPE package!" + getyn "\nAre you sure?" || return 0 + + # Remove wanpipe modules + echo " " + echo "Removing Wanpipe modules" + module_list="sdladrv wanrouter wanpipe_lip wanpipe_syncppp wanpipe af_wanpipe wanec" + for module_name in $module_list + do + eval "modprobe -l |grep $module_name > /dev/null" + if [ $? -eq 0 ]; then + module_path=`modprobe -l |grep $module_name` + \rm -f $module_path >/dev/null + echo " $module_path removed" + else + echo " $module_name module not found" + fi + done + echo "Probing for modules (depmod -a)..." + eval "depmod -a" + + + # Read meta-configuration file. + if [ -f $ROUTER_RC ]; then + source $ROUTER_RC + fi +# X25API_CONF=${X25API_CONF:=$X25API_CONF} + ROUTER_LOG=${ROUTER_LOG:=/var/log/$PROD} + ROUTER_LOCK=${ROUTER_LOCK:=/var/lock/$PROD} + + [ -f $ROUTER_LOCK ] && { + error "Router appears to be running. Stop it first" + return 1 + } + + # Remove start-up scripts. + remove_init + + # Remove log and configuration files. + echo "Removing log and configuration files..." + [ -f $ROUTER_RC ] && rm -f $ROUTER_RC + [ -f $ROUTER_LOG ] && rm -f $ROUTER_LOG + + #FIXME: Find a better way of doing this + if [ "$PKG_NAME" != "wanpipe-lite" ]; then + if [ -d /etc/wanpipe ]; then + rm -rf /etc/wanpipe + fi + else + IFCFG_LIST=`ls /etc/wanpipe/ifcfg-* 2>/dev/null` + for ifcfg in $IFCFG_LIST; do + [ -f "$ifcfg" ] && rm -f $ifcfg + done + fi + + # Remove contents of the home directory. + echo -e "\nYou can now delete $PROD_HOME directory and its contents." + return 0 +} + +# ---------------------------------------------------------------------------- +# Remove initialization scripts. +# ---------------------------------------------------------------------------- +remove_init() +{ + # Examine system bootstrap files. + if [ -d /etc/rc0.d ] + then RC_DIR=/etc + elif [ -d /etc/rc.d/rc0.d ] + then RC_DIR=/etc/rc.d + else return 0 + fi + + + echo "Removing start-up scripts..." + [ -f $RC_DIR/rc2.d/$START_SCRIPT ] && rm -f $RC_DIR/rc2.d/$START_SCRIPT + [ -f $RC_DIR/rc3.d/$START_SCRIPT ] && rm -f $RC_DIR/rc3.d/$START_SCRIPT + [ -f $RC_DIR/rc5.d/$START_SCRIPT ] && rm -f $RC_DIR/rc4.d/$START_SCRIPT + [ -f $RC_DIR/rc5.d/$START_SCRIPT ] && rm -f $RC_DIR/rc5.d/$START_SCRIPT + [ -f $RC_DIR/rc0.d/$STOP_SCRIPT ] && rm -f $RC_DIR/rc0.d/$STOP_SCRIPT + [ -f $RC_DIR/rc1.d/$STOP_SCRIPT ] && rm -f $RC_DIR/rc1.d/$STOP_SCRIPT + [ -f $RC_DIR/rc6.d/$STOP_SCRIPT ] && rm -f $RC_DIR/rc6.d/$STOP_SCRIPT + [ -f $RC_DIR/init.d/$PROD ] && rm -f $RC_DIR/init.d/$PROD + + eval "find $RC_DIR -name 'S*wanrouter' | xargs rm 2> /dev/null" + eval "find $RC_DIR -name 'K*wanrouter' | xargs rm 2> /dev/null" + return 0 +} + +search_rej () +{ + +echo -e "\nLooking for Reject files" +find $SOURCEDIR/. -name '*.rej' > $PROD_HOME/REJECT_FILE +if [ -s $PROD_HOME/REJECT_FILE ] +then + echo -e "\n!!! Reject Files found: check the $PROD_HOME/REJECT_FILE !!!" + echo -e " WARNING: Patching is not completed" + echo -e "\n If the patch version matches the kernel version, there should be " + echo -e " no errors, thus copy a fresh kernel into the $SOURCEDIR" + echo -e " directory and try again." + echo -e "\n If the patch verison is different from the kernel version, check" + echo -e " the reject files in $PROD_HOME/REJECT_FILE. A patch will have" + echo -e " to be added in manually. Refer to the README file in " + echo -e " ftp.sangoma.com /pub/linux/v2.2.X/(Kernel Version) directory. " + echo -e "\n For further assistance email ncorbic@sangoma.com or contact Sangoma" + echo -e " at (905) 474 1990.\n" + pause +else + echo -e "\n PATCH SUCCESSFUL: no reject files found :)\n" + rm $PROD_HOME/REJECT_FILE + pause +fi + +} + +compile_src () +{ + banner + if [ "$PKG_NAME" != "wanpipe-lite" ]; then + + cat << ENDOFTEXT +WANPIPE UTILITIES SETUP + +WANPIPE utilities are used to: + 1) create WANPIPE configuration files. + (/usr/sbin/wancfg) + 2) create configuration files for Zaptel and Asterisk + (/usr/sbin/wancfg_zaptel) + 3) start,stop,restart individual/all devices and interfaces. + (/usr/sbin/wanrouter) + 4) debug line, protocol and driver problems. + (/usr/sbin/wanpipemon) + 5) aid in WANPIPE API development + (/etc/wanpipe/api) + +Refer to the WanpipeInstallation.(pdf/txt) for more information. + +ENDOFTEXT + + pause + fi + + [ -d $INCLUDE ] || { + echo -e "\n\t\tERROR: System environment setup failure !!\n" + echo -e "\tLinux include directory does not exist: $INCLUDE\n" + echo -e "\tCompilation process requires the above path" + echo -e "\tthe $INCLUDE directory must point to the location of the" + echo -e "\tWANPIPE header files, found in linux source include directory\n" + + echo -e "\tPlease install the Linux source in $SOURCEDIR before" + echo -e "\tproceeding" + pause + return 0 + } + + if [ ! -e $SOURCEDIR/include/asm ]; then + echo -e " +WARNING: The Linux source in $SOURCEDIR has not been configured. + Please proceed to configure the source before compiling + wanpipe utilities (ex: make menuconfig and make dep)." + echo + pause + return 0 + fi + + if [ ! -e $SOURCEDIR/include/linux/version.h ]; then + echo -e " +WARNING: The Linux source in $SOURCEDIR has not been configured. + Please proceed to configure the source before compiling + wanpipe utilities (ex: make menuconfig and make dep)." + echo + pause + return 0 + fi + + + check_gcc + if [ $? -ne 0 ]; then + echo + pause + echo -e "\n\tWarning: Wanpipe package requires C development tools to complete + the installation. Please install development package + before proceeding. GCC/KGCC/CC compiler not found" + return 0 + fi + + delete_old_tools; + + cd $PROD_HOME/util + + echo + echo -n "Compiling ${DISTR_NAME} Utilities ..." + + MAKEINC= + + if [ "$ADSL_PROT" = "YES" ]; then + MAKEINC=$MAKEINC" PROTOCOL_DEFS=-DCONFIG_PRODUCT_WANPIPE_ADSL " + fi + if [ $ENABLE_ECHO_DEBUG -eq 1 ]; then + MAKEINC=$MAKEINC" ENABLE_WANPIPEMON_ZAP=YES " + fi + eval "make CC=$CC SYSINC=$SOURCEDIR/include WANINCDIR=$WANPIPE_INCLUDE_DIR $MAKEINC >> $CMP_LOG 2>> $CMP_LOG" + + if [ $? -eq 0 ] + then + echo -e "Done.\n" + else + echo + echo "make CC=$CC SYSINC=$SOURCEDIR/include $MAKEINC" + echo + echo -e "Failed!\n" + echo -e "\n\t\t!!! ${DISTR_NAME} Tools Compilation Failed !!!" + echo -e "\tPossible solution:" + echo -e "\t\t Wanpipe header files were not installed properly" + echo -e "\t\t in $SOURCEDIR/include directory" + echo -e "\tPlease contact Sangoma Tech. at 905 474-1990\n" + pause + return 1 + fi + + + echo + echo "Compiling ${DISTR_NAME} WanCfg Utility ..." + + WANCFG_DEFS= + if [ "$TDM_PROT" = "YES" ]; then + WANCFG_DEFS=$WANCFG_DEFS" ENABLE_ZAPTEL_PARSER=YES ZAPINC=$ZAPTEL_INSTALL_DIR" + fi + eval "make -C wancfg all CC=$CC SYSINC=$SOURCEDIR/include $WANCFG_DEFS >> $CMP_LOG 2>> $CMP_LOG" + + if [ $? -eq 0 ] + then + echo -e "Done.\n" + else + echo + echo -e "Failed!\n" + echo -e "\n\t\t!!! ${DISTR_NAME} WanCfg Compilation Failed !!!" + echo -e "\tPossible solution:" + echo -e "\t\t FLEX Package not installed" + echo -e "\t\t Non-standard C/C++ library (eg: ulibc)\n" + echo -e "\tPlease contact Sangoma Tech. at 905 474-1990\n" + + getyn "Proceed with installation without WanCfg ?" || return 1; + fi + + + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + return 0 + fi + + cd $PROD_HOME/util/misc + + echo + echo -n "Compiling WANPIPE Misc Utilities ..." + eval "make CC=$CC SYSINC=$SOURCEDIR/include > /dev/null" + echo -e "Done.\n" + + echo + echo -n "Compiling WANPIPE LibSangoma TDM API library ..." + + cd $PROD_HOME/api + + cd libsangoma + eval "./configure --prefix=$ROOT/usr/include >> $CMP_LOG 2>> $CMP_LOG" + eval "make clean >> $CMP_LOG 2>> $CMP_LOG" + eval "make CC=$CC SYSINC=$SOURCEDIR/include >> $CMP_LOG 2>> $CMP_LOG" + if [ $? -eq 0 ]; then + echo -e "Done.\n" + else + echo -e "Failed. \n" + pause + fi + eval "make install >> $CMP_LOG 2>> $CMP_LOG" + + + if [ $superuser = "YES" ]; then + if [ -d /etc/ld.so.conf.d ]; then + if [ ! -e $ROOT/etc/ld.so.conf.d/ ]; then + \mkdir -p $ROOT/etc/ld.so.conf.d/ + fi + \cp -f libsangoma.so.conf $ROOT/etc/ld.so.conf.d/ + + if [ $superuser = "YES" ]; then + eval "ldconfig" + fi + elif [ -f /etc/ld.so.conf ]; then + if [ $superuser = "YES" ]; then + cat /etc/ld.so.conf libsangoma.so.conf > ldconf.$$ + mv ldconf.$$ /etc/ld.so.conf + eval "ldconfig" + fi + else + echo + echo "Warning: LD Conf files not found in /etc directory" + echo "Please add /usr/local/lib to the LD_LIBRARY_PATH" + echo + eval "ldconfig" + pause + fi + fi + + echo + echo -n "Compiling WANPIPE API Development Utilities ..." + + cd $PROD_HOME/api + + eval "make CC=$CC SYSINC=$SOURCEDIR/include >> $CMP_LOG 2>> $CMP_LOG" + if [ $? -eq 0 ]; then + echo -e "Done.\n" + else + echo -e "Failed!\n" + echo -e "\tERROR: Failed to compile WANPIPE API Tools !!!" + echo -e "\t\nPlease contact Sangoma Technologies" + pause + fi + + if [ -d $PROD_HOME/util/wanec_client ] && [ -d $DRIVER_UPDATE_DIR/wanec ] ; then + echo + echo -n "Compiling WANPIPE HWEC Utilities ..." + cd $PROD_HOME/util/wanec_client + eval "make CC=$CC SYSINC=$SOURCEDIR/include WANEC_DIR=$DRIVER_UPDATE_DIR/wanec >> $CMP_LOG 2>> $CMP_LOG " + if [ $? -eq 0 ]; then + echo -e "Done.\n" + else + echo -e "Failed!\n" + echo -e "\tERROR: Failed to compile WANPIPE HWEC Tools !!!" + echo -e "\t\nPlease contact Sangoma Technologies" + pause + fi + else + echo + echo -n "WANPIPE HWEC Utilities not installed" + echo + fi + echo -e "\tWANPIPE Environment Setup Complete !!!\n" + pause + return 0 +} + +delete_old_tools() +{ + cd $PROD_HOME/util + make clean 2> /dev/null > /dev/null + + cd $PROD_HOME +} + +check_kernel_patch_level () +{ + + local DIR=$1; + local val + + if [ -f "$DIR/net/wanrouter/patchlevel" ]; then + val=`cat $DIR/net/wanrouter/patchlevel` + echo -e "\tCurrent WANPIPE kernel patch is $val" + if [ $val = "2.0.3" ]; then + return 0 + elif [ $val = "2.2.1" ]; then + if [ $KPATCH -eq 4 ] && [ $KLVL -gt 3 ]; then + return 0 + else + return 1 + fi + else + return 1 + fi + fi + + return 0 +} + +clean_up () +{ + [ -f "/usr/sbin/router" ] && rm -f /usr/sbin/router + + [ -f $RC_DIR/rc2.d/$OLD_START ] && rm -f $RC_DIR/rc2.d/$OLD_START + [ -f $RC_DIR/rc3.d/$OLD_START ] && rm -f $RC_DIR/rc3.d/$OLD_START + [ -f $RC_DIR/rc5.d/$OLD_START ] && rm -f $RC_DIR/rc4.d/$OLD_START + [ -f $RC_DIR/rc5.d/$OLD_START ] && rm -f $RC_DIR/rc5.d/$OLD_START + [ -f $RC_DIR/rc0.d/$OLD_STOP ] && rm -f $RC_DIR/rc0.d/$OLD_STOP + [ -f $RC_DIR/rc1.d/$OLD_STOP ] && rm -f $RC_DIR/rc1.d/$OLD_STOP + [ -f $RC_DIR/rc6.d/$OLD_STOP ] && rm -f $RC_DIR/rc6.d/$OLD_STOP + + [ -f "/etc/router.rc" ] && rm -f /etc/router.rc + +} + +get_distrib() +{ + grep -i "red *hat" "/etc/issue" > /dev/null + if [ $? -eq 0 ] + then + return 1; #RedHat Found + else + return 0; + fi +} + +function check_for_af_wanpipe_updates() +{ + if [ $KVER -eq 2 ] && [ $KPATCH -eq 6 ]; then + if [ $KLVL -eq 11 ]; then + eval "grep sk_zapped $SOURCEDIR/include/net/sock.h > /dev/null 2> /dev/null" + if [ $? -ne 0 ]; then + AF_EXTRA_FLAGS="$AF_EXTRA_FLAGS -DAF_WANPIPE_2612_FORCE_UPDATE" + fi + elif [ $KLVL -gt 11 ]; then + AF_EXTRA_FLAGS="$AF_EXTRA_FLAGS -DAF_WANPIPE_2612_FORCE_UPDATE" + fi + fi +} + +function wan_kernel_version_conflict_fix() +{ + local FLAGS= + + if [ $LINUX_VANILLA -gt 0 ]; then + return; + fi + + if [ $KVER -eq 2 ] && [ $KPATCH -eq 6 ]; then + if [ $KLVL -eq 11 ]; then + if [ "$KEVER" != "" ]; then + FLAGS="$FLAGS -DAF_WANPIPE_2612_FORCE_UPDATE" + fi + elif [ $KLVL -gt 11 ]; then + FLAGS="$FLAGS -DAF_WANPIPE_2612_FORCE_UPDATE" + fi + + if [ $KLVL -eq 5 ]; then + if [ "$KEVER" != "" ]; then + FLAGS="$FLAGS -DWANPIPE_MOD_266_FORCE_UPDATE" + fi + elif [ $KLVL -gt 5 ]; then + FLAGS="$FLAGS -DWANPIPE_MOD_266_FORCE_UPDATE" + fi + fi + + if [ "$FLAGS" != "" ]; then + echo "Wan Update Flags: $FLAGS" + CFLAGS="$CFLAGS $FLAGS " + fi + +} + + +function is_distr_fedora2() +{ + local distr + + if [ ! -f /etc/issue ]; then + return 0 + fi + + distr=`cat /etc/issue | grep "(Tettnang)"` + + #If release is not Fedora2 then + #get out + if [ "$distr" = "" ]; then + return 0 + fi + + return 1 +} + + +function update_redhat_as() +{ + local distr + local rc + local cmd=$1 + + if [ ! -f /etc/issue ]; then + return 0 + fi + + distr=`cat /etc/issue | grep "(Panama)"` + + #If release is not RedHat AS then + #get out + if [ "$distr" = "" ]; then + return 0 + fi + + + if [ ! -f $SOURCEDIR/include/linux/version.h ]; then + return 0 + fi + + if [ $cmd -eq 0 ]; then + + if [ ! -d /tmp ]; then + mkdir /tmp + fi + + \cp -f $SOURCEDIR/include/linux/version.h /tmp/version.h + + rc=`cat /tmp/version.h | awk '{ gsub("132105", "132106") ; print }' > $SOURCEDIR/include/linux/version.h` + else + if [ -f /tmp/version.h ]; then + \cp -f /tmp/version.h $SOURCEDIR/include/linux/version.h + fi + fi + return 0; +} + +function wan_get_kernel_flags() +{ +# echo "make -C $SOURCEDIR SUBDIRS=$PWD drivers/net/wan/sdladrv 2> /dev/null" + + if [ ! -d $SOURCEDIR/wanpipe ]; then + mkdir -p $SOURCEDIR/wanpipe + fi + cp $DRIVER_UPDATE_DIR/src/net/sdladrv.c $SOURCEDIR/wanpipe + + tmp1=`make -C $SOURCEDIR SUBDIRS=$PWD wanpipe/sdladrv 2> /dev/null` + +# echo "TMP =---$tmp---" + + tmp=${tmp1#*gcc} + + tmp1=$tmp; + +# echo "TMP1 =---$tmp1---" + + tmp=${tmp1%%wanpipe/*} + + tmp1=$tmp + + tmp=${tmp1%%-m elf*} + + tmp1=$tmp; + + tmp=${tmp1%%-c *}; + + tmp1=$tmp; + + tmp=${tmp1//-Iinclude\//-I$SOURCEDIR\/include/} + + CFLAGS_EXTRA=$tmp + + if [ $DISABLE_GCC_DEBUG -gt 0 ]; then + tmp=${CFLAGS_EXTRA//-g/} + CFLAGS_EXTRA=$tmp + fi + + if [ "$CFLAGS_EXTRA" = "" ]; then + echo "Major Error: Failed to obtain kernel CFLAGS from $SOURCEDIR" + fi + + if [ -d $SOURCEDIR/wanpipe ]; then + \rm -rf $SOURCEDIR/wanpipe + fi + + #echo "CFLAGS_EXTRA=$CFLAGS_EXTRA" + + + echo +} + +function build_kernel_module() +{ + modname=$1 + modfiles=$2 + extra_flags=$3 + local_link=$4 + bin_link=$4 + ofiles= + + extra_flags=$extra_flags" -I/$WANPIPE_INCLUDE_DIR -I$WANPIPE_INCLUDE_DIR/oct6100_api -I$WANPIPE_INCLUDE_DIR/oct6100_api/oct6100api " + + if [ $KBUILD_DISABLE -ne 1 ] && [ $KERN_VER -eq 26 ]; then + + for file in $modfiles + do + ofiles=$ofiles"$file.o " + local_link=$local_link" $file.o " + done + + + echo "make MODULE_NAME=$modname OBJS=\"$ofiles\" SUBDIRS=$PWD CC=$CC KDIR=$SOURCEDIR \ + EXTRA_CFLAGS=\"-D__LINUX__ $PROTOCOL_DEFINES $extra_flags \"" >> $CMP_BUILD + + chmod 755 $CMP_BUILD + + make MODULE_NAME=$modname OBJS="$ofiles" CC=$CC SUBDIRS=$PWD KBUILD_VERBOSE=$KBUILD_VERBOSE KDIR=$SOURCEDIR \ + EXTRA_CFLAGS="-D__LINUX__ $PROTOCOL_DEFINES $extra_flags " >> $CMP_LOG 2>> $CMP_LOG + + if [ $? -ne 0 ]; then + echo + echo "---------------------------------------------" + echo + cat $CMP_LOG + echo + echo "---------------------------------------------" + echo + exit 1; + else + if [ $KBUILD_VERBOSE -eq 1 ]; then + cat $CMP_LOG + fi + fi + + if [ "$bin_link" != "" ]; then + + #echo "----------------------------" + #echo "ld $LD_ELF -r -o $modname.o $local_link" + #echo "----------------------------" + #echo + + echo "ld $LD_ELF -r -o $modname.o $local_link" >> $CMP_BUILD + $EVALCMD "ld $LD_ELF -r -o $modname.o $local_link" + + #echo "----------------------------" + #echo "ld $LD_ELF -r -o $modname.ko $modname.o $modname.mod.o" + #echo "----------------------------" + #echo + + echo "ld $LD_ELF -r -o $modname.ko $modname.o $modname.mod.o" >> $CMP_BUILD + $EVALCMD "ld $LD_ELF -r -o $modname.ko $modname.o $modname.mod.o" + fi + else + + for file in $modfiles + do + #echo "----------------------------" + #echo "$CFLAGS $PROTOCOL_DEFINES $extra_flags -DKBUILD_BASENAME=$file -DKBUILD_MODNAME=$modname -c -o tmp/$file.o $file.c" + #echo "----------------------------" + #echo + + $EVALCMD "$CFLAGS $PROTOCOL_DEFINES $extra_flags -DKBUILD_BASENAME=$file -DKBUILD_MODNAME=$modname -c -o tmp/$file.o $file.c" + local_link=$local_link" tmp/$file.o " + done + + #echo "----------------------------" + #echo "ld $LD_ELF -r -o mod/$modname.o $local_link" + #echo "----------------------------" + #echo + echo "$EVALCMD \"ld $LD_ELF -r -o mod/$modname.o $local_link\"" >> $CMP_BUILD + $EVALCMD "ld $LD_ELF -r -o mod/$modname.o $local_link" + + if [ $KERN_VER -eq 26 ]; then + + #echo "----------------------------" + #echo "$CFLAGS -DKBUILD_BASENAME=$modname -DKBUILD_MODNAME=$modname -c -o mod/$modname.mod.o $modname.mod.c" + #echo "----------------------------" + #echo + $EVALCMD "$CFLAGS -DKBUILD_BASENAME=$modname -DKBUILD_MODNAME=$modname -c -o mod/$modname.mod.o $modname.mod.c" + + #echo "----------------------------" + #echo "ld $LD_ELF -r -o mod/$modname.ko mod/$modname.o mod/$modname.mod.o" + #echo "----------------------------" + #echo + $EVALCMD "ld $LD_ELF -r -o mod/$modname.ko mod/$modname.o mod/$modname.mod.o" + fi + + fi +} + + +function build_wanec_module () +{ + + local home=`pwd` + + local BTDIR=oct6100_api/apilib/bt + local LARGMATHDIR=oct6100_api/apilib/largmath + local LLMANDIR=oct6100_api/apilib/llman + local OCTAPIDIR=oct6100_api/octdeviceapi/oct6100api/oct6100_api + local OCTAPIMIDIR=oct6100_api/octdeviceapi/oct6100api/oct6100_apimi + + if [ $KERN_VER -eq 24 ]; then + BTDIR=./ + LARGMATHDIR=./ + LLMANDIR=./ + OCTAPIDIR=./ + OCTAPIMIDIR=./ + fi + + local EXTRA_FLAGS="-I. -I$home -I$home/oct6100_api -I$home/oct6100_api/include -I$home/oct6100_api/include -I$home/oct6100_api/include/apilib -I$home/oct6100_api/include/apilib -I$home/oct6100_api/include/octrpc -I$home/oct6100_api/include/oct6100api -I$home/oct6100_api/octdeviceapi/oct6100api -DENABLE_TONE_PLAY " + + + local files="wanec_iface wanec_cmd wanec_utils wanec_dev $BTDIR/octapi_bt0 $LARGMATHDIR/octapi_largmath $LLMANDIR/octapi_llman $OCTAPIMIDIR/oct6100_mask_interrupts $OCTAPIDIR/oct6100_adpcm_chan $OCTAPIDIR/oct6100_channel $OCTAPIDIR/oct6100_chip_open $OCTAPIDIR/oct6100_chip_stats $OCTAPIDIR/oct6100_conf_bridge $OCTAPIDIR/oct6100_debug $OCTAPIDIR/oct6100_events $OCTAPIDIR/oct6100_interrupts $OCTAPIDIR/oct6100_memory $OCTAPIDIR/oct6100_miscellaneous $OCTAPIDIR/oct6100_mixer $OCTAPIDIR/oct6100_phasing_tsst $OCTAPIDIR/oct6100_playout_buf $OCTAPIDIR/oct6100_remote_debug $OCTAPIDIR/oct6100_tlv $OCTAPIDIR/oct6100_tone_detection $OCTAPIDIR/oct6100_tsi_cnct $OCTAPIDIR/oct6100_tsst $OCTAPIDIR/oct6100_user " + + + #eval "make clean > /dev/null 2> /dev/null" + + if [ $KERN_VER -eq 24 ]; then + if [ -e wanectmp ]; then + eval "rm -rf wanectmp 2>" /dev/null + fi + mkdir wanectmp + eval "\cp -rf $(find . -name '*.*' | xargs) wanectmp/" > /dev/null + cd wanectmp + mkdir mod + mkdir tmp + fi + + + build_kernel_module wanec "$files" "$EXTRA_FLAGS" + if [ $? -ne 0 ]; then + return $?; + fi + + if [ $KERN_VER -eq 24 ]; then + cd $home + if [ -e wanectmp/mod/wanec.o ]; then + eval "\cp -f wanectmp/mod/wanec.o ." + fi + eval "rm -rf wanectmp" + fi + + return 0 + +} + +function sangoma_64bit_4g_check() +{ + eval "uname -a | grep x86_64" > /dev/null 2> /dev/null + if [ $? -ne 0 ] ; then + val=`cat /proc/meminfo | grep MemTotal | cut -d':' -f2` + tmp=${val// /} + b=`expr match "$tmp" '\([0-9]*\)'` + morethan4bg=`expr $b \> 4000000` + if [ $morethan4bg -eq 1 ]; then + #More than 4G of memory + return 0; + else + return 1; + fi + fi + + #not 64bit 4G mode + return 1; +} + + +function create_kernel_mod_file() +{ + local file=$1 + eval "$SOURCEDIR/scripts/mod/modpost -m -i $SOURCEDIR/Module.symvers $file 2> /dev/null 2> /dev/null" +} + +function update_kernel_custom_name() +{ + local make_name="fedora2_make" + + if [ ! -f $SOURCEDIR/Makefile ]; then + echo "Error: File $SOURCEDIR/Makefile not found!" + return 1; + fi + + \cp -f $SOURCEDIR/Makefile /tmp/$make_name + + rc=`cat /tmp/$make_name | awk '{ gsub("custom", "") ; print }' > $SOURCEDIR/Makefile` + + cur_home=`pwd` + cd $SOURCEDIR + make prepare-all > /dev/null 2> /dev/null + echo "Kernel name in $SOURCEDIR/Makefile updated successfully ($?)" + cd $cur_home + + echo + return 0 + +} + +function update_fedora2() +{ + local distr + local rc + local cmd=$1 + local ver_name="fedora2_version.h" + + if [ ! -f /etc/issue ]; then + return 1 + fi + + distr=`cat /etc/issue | grep "(Tettnang)"` + + #If release is not Fedora2 then + #get out + if [ "$distr" = "" ]; then + return 1 + fi + + if [ ! -f $SOURCEDIR/include/linux/version.h ]; then + return 0 + fi + + if [ $cmd -eq 0 ]; then + + if [ ! -d /tmp ]; then + mkdir /tmp + fi + + \cp -f $SOURCEDIR/include/linux/version.h /tmp/$ver_name + + rc=`cat /tmp/$ver_name | awk '{ gsub("132613", "132614") ; print }' > $SOURCEDIR/include/linux/version.h` + else + if [ -f /tmp/$ver_name ]; then + \cp -f /tmp/$ver_name $SOURCEDIR/include/linux/version.h + fi + fi + return 0; +} + +function select_compilation_mode() +{ + banner + local response= + + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_GENERIC " + return + fi + + if [ "$PROTS" != "" ]; then + #User has already selected protocols on command line + return; + fi + + cat << ENDOFTEXT + + Please Select Compilation Mode + +1. WAN Protocols Support + Protocols: Frame Relay, CHDLC, PPP, ATM, X25, ADSL, TDM API + Default for: Wan Routing, Data & Voice API devel. + +2. TDM Voice (Zaptel) Support + Protocols: TDMV (Zaptel), TDM API on AFT adatpers. + Default for: Asterisk & CallWeaver + +3. TDM Voice (Zaptel) + WAN Protocol Support + +4. SMG (SS7) (Default for Asterisk SMG/SS7 install) + +5. SMG (SS7) + TDM Voice (Zaptel) + Default for: Asterisk SS7 + PRI + +6. TDM API + Protocols: TDM API on AFT adapters: + Default for: FreeSwitch, Yate, Sunrise + Custom voice development + +7. Custom Compilation Mode + Specify protocols to be added into the WANPIPE + kernel drivers. + +ENDOFTEXT + +echo -n "Please select (1,2,3,4,5,6 or 7) [Default: 1]: " + +if test -z $NONINTERACTIVE; then + + read response + + #if [ -z $response ]; then + # response=1 + #fi + + if [ "$response" -eq 1 ]; then + enable_protocols $DEFAULT_PROTOCOLS + + elif [ "$response" -eq 2 ]; then + enable_protocols "TDM" + enable_protocols "AFT_TE1" + LIP_PROT=NO + LIP_LOAD=NO + + elif [ "$response" -eq 3 ]; then + enable_protocols "TDM" + enable_protocols $DEFAULT_PROTOCOLS + + elif [ "$response" -eq 4 ]; then + enable_protocols "XMTP2" + enable_protocols "AFT_TE1" + + elif [ "$response" -eq 5 ]; then + enable_protocols "TDM" + enable_protocols "XMTP2" + enable_protocols "AFT_TE1" + + elif [ "$response" -eq 6 ]; then + enable_protocols "AFT_TE1" + + elif [ "$response" -eq 7 ]; then + enable_custom_protocols + else + select_compilation_mode + fi +else + if [ "$PROTS" = "" ]; then + enable_protocols $DEFAULT_PROTOCOLS + fi +fi +} + + +function makefile_function () +{ + echo "$1" >> Makefile +} + + + + +function compile_drivers () +{ + + banner + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + + cat << ENDOFTEXT +WANPIPE (LITE) KERNEL DRIVER COMPILATION + +The next step in WANPIPE (LITE) installation involves compiling +WANPIPE (LITE) kernel module. + + Therefore, NO kernel recompilation is required :) + +WANPIPE (LITE) driver attaches to kernel WAN stacks: + * Frame Relay + * PPP + * Cisco HDLC + +Refer to the wanpipe_lite_manual.(pdf/txt) documentation. +ENDOFTEXT + + else + cat << ENDOFTEXT +WANPIPE KERNEL DRIVER COMPILATION + +The next step in WANPIPE installation involves compiling +WANPIPE kernel modules. + +This script will compile and install WANPIPE modules +into the currently running linux kernel. + +For greater customization you will be prompted to +select which Protocol/Drivers you would like to +build into the WANPIPE kernel modules. + +Wanpipe for Asterisk/Zaptel + Default for Asterisk/Zaptel +Wanpipe for Wan Routing/API + Default for Wan/IP Routing and Data API +Wanpipe for Asterisk SMG/SS7 + Default for Asterisk SS7 +Wanpipe for TDM API + Default for FreeSwitch and Voice API + +Custom Compilation: +------------------ + Customise WANPIPE driver compilation to add only the + protocols that you need. This way one can reduce + the size of the WANPIPE kernel drivers. + +Refer to http://wiki.sangoma.com for more info +ENDOFTEXT + fi + + if [ -d "$DRIVER_TMP_DIR" ]; then + rm -rf $DRIVER_TMP_DIR + fi + + \mkdir "$DRIVER_TMP_DIR" + \mkdir "$DRIVER_TMP_DIR/mod" + \mkdir "$DRIVER_TMP_DIR/tmp" + + get_kernel_ver $SOURCEDIR + if [ $? -eq 1 ]; then + pause + return 1 + fi + + echo + getyn "Proceed to build ${DISTR_NAME} kernel modules ? [y]" || return 0; + if [ ! -d $DRIVER_TMP_DIR ]; then + eval "\mkdir -p $DRIVER_TMP_DIR > /dev/null" + if [ $? -ne 0 ]; then + echo "ERROR: Failed to create $DRIVER_TMP_DIR directory!!!" + pause + return 1 + fi + fi + + ANNEXG_LOAD=NO + + check_gcc + if [ $? -ne 0 ]; then + echo + pause + echo -e "\n\tWarning: Wanpipe package requires C development tools to complete + the installation. Please install development package + before proceeding. GCC/KGCC/CC compiler not found!" + return 1 + fi + + if [ ! -f $SOURCEDIR/.config ] && [ -d $SOURCEDIR/configs ]; then + + tmp_k_ver="$KVER"."$KPATCH"."$KLVL" + tmp_k_arch=`uname -m` + tmp_smp=`uname -a | grep SMP` + if [ ! -z $tmp_smp ]; then + tmp_config_file="kernel-$tmp_k_ver-$tmp_k_arch-smp.config" + else + tmp_config_file="kernel-$tmp_k_ver-$tmp_k_arch.config" + fi + + if [ -f $SOURCEDIR/configs/$tmp_config_file ] && ! test $NONINTERACTIVE; then + + echo + echo " Warning:" + echo " The Linux source in $SOURCEDIR doesn't have a .config" + echo " file." + echo + echo " Would you like me to configure the Linux source based" + echo " on the currently running Linux image: $KERNEL_UNAME" + echo + + getyn " Configure the Linux source for $KERNEL_UNAME ?" + if [ $? -eq 0 ]; then + tmp_home=`pwd` + cd $SOURCEDIR + \cp -f $SOURCEDIR/configs/$tmp_config_file $SOURCEDIR/.config + eval "make oldconfig_nonint > /dev/null 2> /dev/null" + if [ $KERN_VER -eq 26 ]; then + eval "make prepare0 > /dev/null 2> /dev/null" + fi + cd $tmp_home + echo + echo " Linux source config completed successfuly" + pause + fi + fi + fi + + + + if [ ! -d $SOURCEDIR/include/asm ] || [ ! -f $SOURCEDIR/include/linux/autoconf.h ]; then + echo -e "\n" + echo "ERROR: The $SOURCEDIR contains a fresh, unconfigured kernel!" + echo "" + echo " If you already have a working kernel image, a" + echo " simple kernel configuration can solve this problem" + echo " In linux source dirctory run: " + echo + echo " make dep modules" + echo + echo " Then retry the Setup script !!" + echo "" + echo " If you are still expriencing problems please contact" + echo " Sangoma Tech Support" + pause + return 1 + fi + +# if [ $KERN_VER -ne 26 ] && [ ! -f $SOURCEDIR/include/linux/modversions.h ]; then +# echo -e "\n" +# echo "ERROR: The $SOURCEDIR contains a fresh, unconfigured kernel!" +# echo +# echo " If you already have a working kernel image, a" +# echo " simple kernel configuration can solve this problem" +# echo " In linux source dirctory run: " +# echo +# echo " make dep modules" +# echo +# echo " Then retry the Setup script !!" +# echo +# echo " If you are still expriencing problems please contact" +# echo " Sangoma Tech Support" +# pause +# return 1 +# fi + + eval "grep \"define *CONFIG_WAN_ROUTER *1\" $SOURCEDIR/include/linux/autoconf.h > /dev/null" + if [ $? -eq 0 ]; then + echo -e "\n" + echo "ERROR: The ${DISTR_NAME} drivers in $SOURCEDIR have been" + echo " configured/compiled into the kernel." + echo " It's usually recommended that drivers be compiled" + echo " as modules." + echo + echo " Please contact Sangoma Tech Support" + echo + pause + return 1 + fi + + + eval "grep \"define *CONFIG_MODVERSIONS\" $SOURCEDIR/include/linux/autoconf.h > /dev/null" + if [ $? -eq 0 ]; then + if [ $KERN_VER -ne 26 ]; then + MODVER=" -DMODVERSIONS -include $SOURCEDIR/include/linux/modversions.h " + fi + MOD_ENABLED=y + else + MODVER="" + MOD_ENALBED=n + fi + + cd $DRIVER_TMP_DIR + + #Copy the WANPIPE device drivers + #into a temporary directory + + eval "\cp -f $DRIVER_UPDATE_DIR/src/net/* . >/dev/null 2>/dev/null" + eval "\cp -f $DRIVER_UPDATE_DIR/src/wanrouter/* .>/dev/null 2>/dev/null" + + + eval "\cp -f $PROD_HOME/kbuild/Makefile . >/dev/null 2>/dev/null" + + for file in $DRIVERS_MOD_LIST + do + eval "\cp $DRIVER_UPDATE_DIR/src/net/$file . >/dev/null 2>/dev/null" + done + + update_redhat_as 0 + update_fedora2 0 + + select_compilation_mode + + #Disply all supported protocols that will be compiled + #into the driver. + + if [ "$PKG_NAME" != "wanpipe-lite" ]; then + echo -e "\n\tSupported WAN Protocols:\n" + fi + + if [ $FR_PROT = YES ]; then + cat << ENDOFTEXT +- Frame Relay + Support for frame relay routing, API, or + bridging. +ENDOFTEXT + fi + + if [ $CHDLC_PROT = YES ]; then + cat << ENDOFTEXT +- Cisco HDLC + Support for Dual Port Cisco HDLC routing + API, and TTY PPP over HDLC Streaming on + S514-PCI/S508-ISA cards. +ENDOFTEXT + fi + + if [ $PPP_PROT = YES ]; then + cat << ENDOFTEXT +- PPP + Support for PPP routing on S514-PCI/S508-ISA cards. +ENDOFTEXT + fi + if [ "$PKG_NAME" != "wanpipe-lite" ]; then + pause + fi + echo + + + if [ $MPPP_PROT = YES ]; then + cat << ENDOFTEXT +- Multi Protocol Driver + Support for kernel RawHDLC/PPP/CHDLC/X25 + on each Sangoma adapter (S514-PCI/S508-ISE) + port PRI and SEC. +ENDOFTEXT + fi + + if [ $MFR_PROT = YES ]; then + cat << ENDOFTEXT +- Multi-Port Frame Relay + Support for kernel Frame Relay over HDLC streaming. + This protocol can support a frame relay link + on each Sangoma port (PRI and SEC) on S514/S508 cards. +ENDOFTEXT + fi + + if [ $ANNEXG_PROT = YES ]; then + cat << ENDOFTEXT +- MP API + Support for Kernel LAPB/X25/DSP Protocol Stack. + The MP API Stacks can run on both PRI and SEC ports on S514/S508 + adapters. Furthermore, MP API Stacks can be configured + to run on top of MP Frame Relay or MP Protocol drivers. +ENDOFTEXT + fi + + + if [ $X25_PROT = YES ]; then + cat << ENDOFTEXT +- X25 + Support for X25 routing and API on S514 and S508 + cards. +ENDOFTEXT + fi + + if [ "$PKG_NAME" != "wanpipe-lite" ] ;then + cat << ENDOFTEXT +- API Socket + Support for X25, HDLC, CHDLC and Frame Relay API + socket development. + +ENDOFTEXT + fi + + pause + echo + + if [ "$BISYNC_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- BiSync API + Support for MultiPoint Bisync API on S514 and S508 + cards. Used for connecting to real Bisync network. +ENDOFTEXT + pause + echo + fi + + if [ "$BSCSTRM_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- BiSync Streaming API + Support for Bisync Streaming API on S514 and S508 + cards. Used for receiving custom Bisync data via + custom APIs. +ENDOFTEXT + pause + echo + fi + + if [ "$SS7_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- SS7 Level2 API + Support for SS7 Level2 API on S514 and S508 + cards. + +ENDOFTEXT + pause + echo + fi + + if [ "$ADSL_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- ADSL Protocol + Support for S518 ADSL cards. + Protocols: Ethernet over ATM (LLC/VC) (PPPoE) + Classical IP over ATM (LLC/VC) + PPP over ATM (LLC/VC) + Standards: T.413, G.DMT, G.lite ... + +ENDOFTEXT + pause + echo + fi + + + if [ "$AFT_TE1_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- AFT TE1 Support + Support for AFT TE1 Cards. + Protocols: Frame Relay + PPP + CHDLC + API: HDLC (Raw) + Transparent Bitstreaming + +ENDOFTEXT + pause + echo + fi + + if [ "$AFT_TE3_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- AFT TE3 Support + Support for AFT TE3 Cards. + Protocols: Frame Relay + PPP + CHDLC + API: HDLC (Raw) + Transparent Bitstreaming + +ENDOFTEXT + pause + echo + fi + + + if [ "$ATM_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- ATM Protocol + Support for AFT and S514-(X) T1/E1/V35 cards. + Protocols: Ethernet over ATM (AAL5) (LLC/VC) (PPPoE) + PPP over ATM (PPPoA) (LLC/VC) AFT Only + Classical IP over ATM (LLC/VC) + +ENDOFTEXT + pause + echo + fi + + if [ "$KATM_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- Linux Kernel ATM Stack Protocol + Support for AFT T1/E1 cards. + Protocols: Kernel ATM Stack over AFT ATM (AAL5) + +ENDOFTEXT + pause + echo + fi + + + if [ "$XMTP2_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- XMTP2 SS7 Protocol + Support for LIP XMTP2 AFT cards only. + +ENDOFTEXT + pause + echo + fi + + + + if [ "$ECHO_MASTER_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- TDMV Echo Detection and Control (EDAC) Feature + Support for A102/A104 TDMV cards. + +ENDOFTEXT + pause + echo + fi + + + if [ "$SDLC_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- SDLC API Protocol + Support for SDLC API protocol on S514/S508 cards. + +ENDOFTEXT + pause + echo + fi + + if [ "$EDU_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- EDU API Protocol + Support for Educational Development package over + S514/S508 cards. + +ENDOFTEXT + pause + echo + fi + + if [ "$BITSTRM_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- BITSTRM Protocol + Support for Bitstream Protocol over S514/S508 cards. + Bitstream protocol can Tx/Rx data over individual + T1/E1 DS0's as well as Tx/Rx raw bit streams. + +ENDOFTEXT + pause + echo + fi + + if [ "$POS_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- POS S509/S515 Hardware/Protocol Support + Support for Point of Sale (POS) protocol over + S515/S509 cards. Point of Sale protocols include I + BM 4860, NCR 2126, NCR 1255. + +ENDOFTEXT + pause + echo + fi + + if [ "$ADCCP_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- ADCCP Lapb API Protocol Support + Support for ADCCP Lapb API protocol over + S514/S508 Cards. + +ENDOFTEXT + pause + echo + fi + + if [ "$ASYHDLC_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- Async HDLC API Protocol Support + Support for Async HDLC support over S514/S508 Cards. + +ENDOFTEXT + pause + echo + fi + + + if [ "$TDM_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- TDM Voice Hardware Support for Asterisk PBX Software + Hardware Support for Asterisk PBX Software over + AFT T1/E1 Cards. + +ENDOFTEXT + pause + echo + fi + + if [ "$XDLC_PROT" = "YES" ]; then + cat << ENDOFTEXT + +- XDLC API Support + LIP XDLC Support + +ENDOFTEXT + pause + echo + fi + + + + + + if test -z $NONINTERACTIVE; then + if [ -e $SOURCEDIR/include/config/kernel.release ]; then + KERNEL_VERSION=`cat $SOURCEDIR/include/config/kernel.release` + echo "Source kernel name:$KERNEL_VERSION" + fi + + + if [ $KERNEL_VERSION != $KERNEL_UNAME ]; then + echo + echo -e "WARNING: Module installation dir mismatch!" + echo -e " Linux source name = $KERNEL_VERSION" + echo -e " Current image name = $KERNEL_UNAME" + echo + echo -e " If you are building wanpipe modules for the" + echo -e " currently running image, use the $KERNEL_UNAME" + echo -e " directory (i.e. select 'y') " + echo + + + getyn "Install modules for current image: $KERNEL_UNAME ?" + if [ $? -eq 0 ]; then + KERNEL_VERSION=$KERNEL_UNAME; + + is_distr_fedora2 + if [ $? -eq 1 ]; then + echo + echo -e " Fedora2 Update: " + echo -e " In order to compile for the current kernel" + echo -e " The word 'custom' must be taken out of the" + echo -e " $SOURCEDIR/Makefile" + echo -e " Then in $SOURCEDIR/ run 'make prepare-all'" + echo + getyn "Would you like us to do it for you ?" + if [ $? -eq 0 ]; then + update_kernel_custom_name + update_fedora2 0 + if [ $? -ne 0 ]; then + echo + echo "Auto configuration failed!" + echo "Proceed to make above changes manually!" + echo "Then restart the ./Setup process" + echo + pause + return 1 + fi + else + echo + echo "Proceed to make above changes manually!" + echo "Then restart the ./Setup process" + echo + pause + return 1 + fi + fi + fi + echo + echo "Installing modules for kernel: $KERNEL_VERSION !" + echo + fi + fi + + if [ $ANNEXG_PROT = "YES" ]; then + cp -f $DRIVER_UPDATE_DIR/include/annexg/*.h . + fi + + echo + echo -n "Checking for SMP support ..." + eval "grep \"CONFIG_SMP *1\" $SOURCEDIR/include/linux/autoconf.h > /dev/null" + if [ $? -eq 0 ]; then + echo -e "Enabled.\n" + CONFIG_SMP=YES; + elif [ $FORCE_SMP ] && [ $FORCE_SMP=YES ]; then + echo -e "Forced.\n" + CONFIG_SMP=YES; + else + echo -e "Disabled.\n" + eval "uname -a |grep SMP > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo + echo " Warning: Current image is configured for SMP" + getyn " Would you like to proceed with installation?" + if [ $? -ne 0 ]; then + exit 1 + fi + fi + CONFIG_SMP=NO; + fi + + + #Find out our processor type. This is needed to properly + #compile our modules. +if [ 1 ]; then + ARCH=i386 + echo -n "Checking current processor type ...Forcing to i386" +else + echo -n "Checking current processor type ..." + if [ -z $ARCH ]; then + ARCH=`uname -m` + fi + echo -e "$ARCH\n" +fi + LD_ELF= + + case $ARCH in + + x86_64*) LD_ELF="-m elf_x86_64" + ;; + ia64*) LD_ELF=" -T $SOURCEDIR/arch/ia64/module.lds " + ;; + i686*) LD_ELF="-m elf_i386" + ;; + i586*) ARCH=i386 + LD_ELF="-m elf_i386" + ;; + i486*) ARCH=i386 + LD_ELF="-m elf_i386" + ;; + i386*) LD_ELF="-m elf_i386" + ;; + ppc*) + ;; + *) + echo "Error: Unsuppored architecture type $ARCH!" + pause + return 1 + ;; + esac + + REGPARM_OPT="" + + if [ "$USER_CFLAGS" != "" ]; then + echo + echo "Appending User CFLAGS: $USER_CFLAGS" + echo + fi + + wan_kernel_version_conflict_fix + + if [ "$USE_CFLAGS" != "" ]; then + echo + echo "Compiling with user CFLAGS: $USE_CFLAGS" + echo + CFLAGS=$USE_CFLAGS; + fi + + #Setup the COMPILATOIN FLAGS depending on the kernel type + if [ $KERN_VER -eq 26 ]; then + if [ "$USE_CFLAGS" = "" ]; then +CFLAGS="$CC -Wp,-MD,.wanpipe.o.d -nostdinc -iwithprefix include -D__LINUX__ -Dlinux -D__KERNEL__ -I$SOURCEDIR/include -DMODULE $CFLAGS" + wan_get_kernel_flags + CFLAGS="$CFLAGS $CFLAGS_EXTRA" + fi + + check_inode_struct + + if [ 1 -eq 1 ]; then + echo + echo "--------------------------------------------------" + echo "CFLAGS: $CFLAGS" + echo "--------------------------------------------------" + echo + fi + + echo -n "Checking for REGPARM kernel option ..." + eval "grep \"define *CONFIG_REGPARM *1\" $SOURCEDIR/include/linux/autoconf.h > /dev/null" + if [ $? -eq 0 ]; then + echo -e "Enabled.\n" + REGPARM_OPT=".regparm" + else + + #Taken from kernel Makefile + SUBARCH=$( uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ + -e s/arm.*/arm/ -e s/sa110/arm/ \ + -e s/s390x/s390/ -e s/parisc64/parisc/ \ + -e s/ppc.*/powerpc/ -e s/mips.*/mips/ ) + + + #New way of checking REGPARM because its enabled + #by default on 2.6.20 kernel and up + if [ $SUBARCH != "" ]; then + eval "grep \"CFLAGS.*=.*-pipe.*regparm\" $SOURCEDIR/arch/$SUBARCH/Makefile" > /dev/null 2> /dev/null + if [ $? -eq 0 ]; then + echo -e "Enabled.\n" + REGPARM_OPT=".regparm" + else + echo -e "Disabled.\n" + fi + else + echo -e "Disabled.\n" + fi + fi + + + + + + echo -n "Compiling General ${DISTR_NAME} Driver for 2.6.X Kernel ." + + + elif [ $KERN_VER -eq 24 ]; then + echo -n "Compiling General ${DISTR_NAME} Driver for 2.4.X Kernel ." + + if [ "$USE_CFLAGS" = "" ]; then + + case $ARCH in + + x86_64*) + CFLAGS="$CC -D__LINUX__ -Dlinux -D__KERNEL__ -I$SOURCEDIR/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -Wno-unused -fomit-frame-pointer -mno-red-zone -mcmodel=kernel -pipe -fno-reorder-blocks -finline-limit=2000 -fno-strength-reduce -fno-asynchronous-unwind-tables -nostdinc -iwithprefix include -DMODULE -DEXPORT_SYMTAB" + ;; + + *) + if [ $KLVL -lt 32 ]; then + CFLAGS="$CC -D__LINUX__ -Dlinux -D__KERNEL__ -I$SOURCEDIR/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -march=$ARCH -DMODULE -DEXPORT_SYMTAB" + else + CFLAGS="$CC -D__LINUX__ -Dlinux -D__KERNEL__ -I$SOURCEDIR/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fomit-frame-pointer -pipe -mpreferred-stack-boundary=2 -march=$ARCH -fno-unit-at-a-time -DMODULE -nostdinc -iwithprefix include -DMODULE -DEXPORT_SYMTAB" + fi + + #Old gcc do not have this option, thus we must check for it. + eval "$CC -mpreferred-stack-boundary=2 -S -o /dev/null \ + -xc /dev/null >/dev/null 2>&1" + if [ $? -eq 0 ]; then + CFLAGS=$CFLAGS" -mpreferred-stack-boundary=2 " + fi + + ;; + esac + + fi + else + echo "ERROR: Unsupported Kernel Version $(uname -r)" + pause + return 1 + fi + + if [ $CONFIG_SMP = YES -a $KERN_VER -eq 22 ]; then + CFLAGS=$CFLAGS" -D__SMP__" + fi + + CFLAGS="$CFLAGS $MODVER" + + if [ "$TDM_PROT" = "YES" ]; then + CFLAGS="$CFLAGS $ASTERISK_IFLAGS" + fi + + if [ "$USER_CFLAGS" != "" ]; then + CFLAGS="$CFLAGS $USER_CFLAGS" + fi + + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + flag=`grep "cisco_proto" $SOURCEDIR/include/linux/if.h 2> /dev/null` + if [ -z "$flag" ]; then + CFLAGS=$CFLAGS" -DOLD_IFSETTINGS_STRUCT" + fi + fi + + if [ -d "$DRIVER_UPDATE_DIR/wanec" ]; then + PROTOCOL_DEFINES=$PROTOCOL_DEFINES" -DCONFIG_WANPIPE_HWEC " + fi + + #Compile all individual protocols first + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=wanpipe_main -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/wanpipe_main.o wanpipe_main.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=wanpipe_hdlc -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/wanpipe_hdlc.o wanpipe_hdlc.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=wanpipe_linux_iface -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/wanpipe_linux_iface.o wanpipe_linux_iface.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdla_56k -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/sdla_56k.o sdla_56k.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdla_te1 -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/sdla_te1.o sdla_te1.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdla_8te1 -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/sdla_8te1.o sdla_8te1.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdla_te3 -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/sdla_te3.o sdla_te3.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=wanpipe_utils -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/wanpipe_utils.o wanpipe_utils.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdla_abstr -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/wanpipe_abstr.o wanpipe_abstr.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdladrv -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/sdladrv.o sdladrv.c sdladrv_fe.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdla_xilinx -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/sdla_xilinx.o sdla_xilinx.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdla_aft_te1 -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/sdla_aft_te1.o sdla_aft_te1.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=aft_a104 -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/aft_a104.o aft_a104.c" + eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=aft_analog -DKBUILD_MODNAME=wanpipe_lite \ + -c -o tmp/aft_analog.o aft_analog.c" + + if [ $? -eq 0 ]; then + echo -e "Done.\n" + else + echo -e "Failed!\n" + fi + + MEXT=o + if [ $KERN_VER -eq 26 ]; then + MEXT=ko + fi + eval "ld $LD_ELF -r -o mod/wanpipe_lite.$MEXT tmp/wanpipe_main.o tmp/wanpipe_hdlc.o \ + tmp/wanpipe_linux_iface.o tmp/sdla_te1.o tmp/sdla_8te1.o tmp/sdla_te3.o tmp/sdla_56k.o \ + tmp/wanpipe_utils.o tmp/wanpipe_abstr.o tmp/sdla_xilinx.o tmp/sdla_aft_te1.o \ + tmp/sdladrv.o tmp/aft_a104.o tmp/aft_analog.o " + + install -D -m 644 mod/wanpipe_lite.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_lite.$MEXT + +# End of LITE + else + + if [ 0 -eq 1 ]; then + echo + echo "ALLFLAGS" + echo "--------------------------------------------------" + echo "$CFLAGS" + echo "--------------------------------------------------" + echo + echo + fi + + if [ 0 -eq 1 ]; then + echo + echo "---------------------------------" + echo "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=wanmain -DKBUILD_MODNAME=wanrouter -c -o tmp/wanmain.o wanmain.c" + echo "---------------------------------" + echo + fi + +cat < $PROD_HOME/Compile_Setup.sh + +#!/bin/sh + +if [ -e kdrvcmp ]; then + rm -rf kdrvcmp +fi + +mkdir kdrvcmp +cd kdrvcmp +ln -s . common +ln -s . modinfo +mkdir tmp +mkdir mod + +cp -f ../patches/kdrivers/src/net/* . +cp -f ../patches/kdrivers/src/wanrouter/* . +cp -f ../patches/kdrivers/src/lip/* . +cp -f ../patches/kdrivers/src/lip/bin/* . +cp -rf ../patches/kdrivers/include/* /usr/src/linux/include/linux +cp -rf ../patches/kdrivers/include/* /usr/include/linux +cp -f ../samples/Makefile . +cp -f ../Compile.sh . + +chmod 755 Compile.sh + +cd .. + +echo "Compile Environmet Setup" + +ENDOFTEXT + + +tmp=${CFLAGS/$CC/} +cat < $PROD_HOME/Compile.sh + +#!/bin/sh + +make CFLAGS="$tmp" PROTOCOL_DEFINES="$PROTOCOL_DEFINES" + +ENDOFTEXT + +tmp=${CFLAGS/$CC/} +cat < $PROD_HOME/GCFLAGS +$tmp $PROTOCOL_DEFINES +ENDOFTEXT + + +EVALCMD=eval +WANPIPE_OBJS= + + rm -f sdladrv_src.c + ln -s sdladrv.c sdladrv_src.c + build_kernel_module sdladrv "sdladrv_src sdladrv_fe" + + build_kernel_module wanrouter "wanmain wanproc waniface" + + AF_EXTRA_FLAGS="-DCONFIG_PRODUCT_WANPIPE_SOCK_DATASCOPE" + check_for_af_wanpipe_updates + + rm -f af_wanpipe_src.c + ln -s af_wanpipe.c af_wanpipe_src.c + build_kernel_module af_wanpipe "af_wanpipe_src af_wanpipe_datascope" "$AF_EXTRA_FLAGS" + + echo -n "." + + if [ "$FR_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_fr " + fi + + if [ "$CHDLC_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_chdlc " + fi + + if [ "$PPP_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_ppp " + fi + + echo -n "." + + if [ "$X25_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_x25 " + fi + + if [ "$MPPP_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"wanpipe_multppp " + SYNCPPP_PROT=YES + fi + if [ "$MFR_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_mp_fr " + fi + + + if [ "$ANNEXG_PROT" = "YES" ]; then + + #ANNEXG_X25_FLAGS="-DX25_SW -DX25_SWITCH_DEFAULT_API " + ANNEXG_X25_FLAGS=" " + + for file in $DRIVERS_MPAPI_X25 + do + \cp $DRIVER_UPDATE_DIR/src/net/annexg/$file . + done + for file in $DRIVERS_MPAPI_LAPB + do + \cp $DRIVER_UPDATE_DIR/src/net/annexg/$file . + done + for file in $DRIVERS_MPAPI_DSP + do + \cp $DRIVER_UPDATE_DIR/src/net/annexg/$file . + done + for file in $DRIVERS_MPAPI_MOD_FILES + do + \cp $DRIVER_UPDATE_DIR/src/net/annexg/$file . + done + + build_kernel_module wanpipe_lapb "lapb_iface lapb_in lapb_out lapb_proc lapb_subr lapb_timer lapb_x25_iface" + + build_kernel_module wanpipe_x25 "x25_api_iface x25_dsp_iface x25_facils x25_iface x25_in x25_out x25_proc x25_subr x25_switch x25_timer x25_utils" + + + build_kernel_module wanpipe_dsp "dsp_api_iface dsp_iface dsp_in dsp_out dsp_proc dsp_subr dsp_timer " + fi + + + + + if [ "$SS7_PROT" = "YES" ]; then + + + \cp $DRIVER_UPDATE_DIR/src/net/sdla_ss7.c . + if [ "$SS7_USER_ID" = "" ]; then + echo -e "Failed!\n" + echo + echo "ERROR: SS7 User ID must be suppiled!" + pause + return 0 + fi + + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_ss7 " + fi + + if [ "$EDU_PROT" = "YES" ]; then + \cp $DRIVER_UPDATE_DIR/src/net/sdla_edu.c . + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_edu " + fi + + if [ "$BISYNC_PROT" = "YES" ]; then + \cp $DRIVER_UPDATE_DIR/src/net/sdla_bsc.c . + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_bsc " + + fi + + if [ "$BSCSTRM_PROT" = "YES" ]; then + \cp $DRIVER_UPDATE_DIR/src/net/sdla_bscstrm.c . + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_bscstrm " + fi + + echo -n "." + + if [ "$BITSTRM_PROT" = "YES" ]; then + + \cp $DRIVER_UPDATE_DIR/src/net/sdla_bitstrm.c . + + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_bitstrm " + SYNCPPP_PROT=YES + fi + + if [ "$ADSL_PROT" = "YES" ]; then + + \cp $DRIVER_UPDATE_DIR/src/net/sdla_adsl.c . + + adsl_file=wanpipe_adsl.gcc$GCC_VER.$ARCH$REGPARM_OPT.o + if [ ! -e $DRIVER_UPDATE_DIR/src/bin/$adsl_file ]; then + echo "Warning: ADSL Binary $adsl_file not found!" + echo "Using wanpipe_adsl.gcc3.i386.o" + adsl_file=wanpipe_adsl.gcc3.i386.o + fi + + \cp $DRIVER_UPDATE_DIR/src/bin/$adsl_file tmp/wanpipe_adsl.o + \cp $DRIVER_UPDATE_DIR/src/bin/$adsl_file wanpipe_adsl.o + + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_adsl " + WANPIPE_BIN_OBJS=$WANPIPE_BIN_OBJS"wanpipe_adsl.o " + SYNCPPP_PROT=YES + fi + + if [ "$ATM_PROT" = "YES" ]; then + + \cp $DRIVER_UPDATE_DIR/src/net/sdla_atm.c . + + atm_file=wanpipe_atm.gcc$GCC_VER.$ARCH$REGPARM_OPT.o + if [ ! -e $DRIVER_UPDATE_DIR/src/bin/$atm_file ]; then + echo "Warning: ATM Binary $atm_file not found!" + echo "Using wanpipe_atm.gcc3.i386.o" + atm_file=wanpipe_atm.gcc3.i386.o + fi + + \cp $DRIVER_UPDATE_DIR/src/bin/$atm_file tmp/wanpipe_atm.o + \cp $DRIVER_UPDATE_DIR/src/bin/$atm_file wanpipe_atm.o + + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_atm " + WANPIPE_BIN_OBJS=$WANPIPE_BIN_OBJS"wanpipe_atm.o " + + SYNCPPP_PROT=YES + fi + + if [ "$ECHO_MASTER_PROT" = "YES" ]; then + + echo_file=wanpipe_edac.gcc$GCC_VER.$ARCH$REGPARM_OPT.o + if [ ! -e $DRIVER_UPDATE_DIR/src/bin/$echo_file ]; then + echo "Warning: ECHO MASTER Binary $echo_file not found!" + echo "Using wanpipe_edac.gcc3.i386.o" + echo_file=wanpipe_edac.gcc3.i386.o + fi + + \cp $DRIVER_UPDATE_DIR/src/net/sdla_edac.c . + \cp $DRIVER_UPDATE_DIR/src/bin/$echo_file tmp/wanpipe_edac.o + \cp $DRIVER_UPDATE_DIR/src/bin/$echo_file wanpipe_edac.o + + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_edac " + WANPIPE_BIN_OBJS=$WANPIPE_BIN_OBJS"wanpipe_edac.o " + + fi + + + if [ "$SDLC_PROT" = "YES" ]; then + \cp $DRIVER_UPDATE_DIR/src/net/sdla_sdlc.c . + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_sdlc " + fi + + if [ "$POS_PROT" = "YES" ]; then + \cp $DRIVER_UPDATE_DIR/src/net/sdla_pos.c . + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_pos " + fi + + if [ "$ADCCP_PROT" = "YES" ]; then + \cp $DRIVER_UPDATE_DIR/src/net/sdla_adccp.c . + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_adccp " + fi + + if [ "$ASYHDLC_PROT" = "YES" ]; then + \cp $DRIVER_UPDATE_DIR/src/net/sdla_asyhdlc.c . + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_asyhdlc " + fi + + if [ "$TDM_PROT" = "YES" ]; then + \cp $DRIVER_UPDATE_DIR/src/net/sdla_tdmv.c . + \cp $DRIVER_UPDATE_DIR/src/net/sdla_remora_tdmv.c . + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_tdmv sdla_remora_tdmv " + WANPIPE_EXTRA_CFLAGS=$WANPIPE_EXTRA_CFLAGS"-I$ZAPTEL_INSTALL_DIR " + fi + + if [ "$AFT_TE1_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_xilinx sdla_aft_te1 aft_a104 sdla_remora aft_analog " + fi + + if [ "$AFT_TE3_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_aft_te3 " + fi + + + if [ "$SYNCPPP_PROT" = "YES" ]; then + rm -f wanpipe_syncppp_src.c + ln -s wanpipe_syncppp.c wanpipe_syncppp_src.c + build_kernel_module wanpipe_syncppp wanpipe_syncppp_src + fi + + echo -n "." + + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_56k sdla_te1 sdla_8te1 sdla_te3 sdla_ft1 wanpipe_utils wanpipe_abstr wanpipe_linux_iface " + + + + if [ $? -eq 0 ]; then + echo -e "Done.\n" + else + echo -e "Failed!\n" + return 1 + fi + + if [ "$WAN_FRM_UPDATE_DRIVER" = "YES" ] && + [ -d "$DRIVER_UPDATE_DIR/src/wan_aften" ]; then + + echo + \cp -f $DRIVER_UPDATE_DIR/src/wan_aften/*.c . + \cp -f $DRIVER_UPDATE_DIR/src/wan_aften/*.h . + + rm -f wan_aften_src.c + ln -s wan_aften.c wan_aften_src.c + build_kernel_module wan_aften "wan_aften_src wanpipe_linux_iface" + fi + + if [ -d "$DRIVER_UPDATE_DIR/wanec" ]; then + + home_tmp=`pwd` + cd $DRIVER_UPDATE_DIR/wanec + \cp -f $PROD_HOME/kbuild/Makefile.wanec Makefile + build_wanec_module + if [ $? -eq 0 ]; then + echo "WAN HWEC module enabled and compiled!" + else + echo "WAN HWEC module failed to compile!" + fi + cd $home_tmp + + fi + + if [ "$LIP_PROT" = "YES" ]; then + + LIP_LOAD="YES"; + LIP_BIN_OBJS= + LIP_OBJS= + + echo + \cp -f $DRIVER_UPDATE_DIR/src/lip/*.c . + \cp -f $DRIVER_UPDATE_DIR/src/lip/bin/*.o . + + if [ -e $DRIVER_UPDATE_DIR/src/lip/lip_katm ]; then + \cp -f $DRIVER_UPDATE_DIR/src/lip/lip_katm/*.c . + \cp -f $DRIVER_UPDATE_DIR/src/lip/lip_katm/*.h . + fi + + LIP_LINKED_PROTOCOLS= + + TMP_CFLAGS="-I/$WANPIPE_INCLUDE_DIR -I/ -I$SOURCEDIR/include -I$SOURCEDIR/include/linux -I../include/common -I../include " + if [ "$REGPARM_OPT" = ".regparm" ]; then + TMP_CFLAGS=$TMP_CFLAGS" -mregparm=3 " + fi + + if [ $FR_PROT = "YES" ]; then + if [ -e $DRIVER_UPDATE_DIR/fr ]; then + + echo -n "Compiling Frame Relay sources..." + lhome=`pwd` + cd $DRIVER_UPDATE_DIR/fr + + eval "rm -f *.o" >/dev/null 2>/dev/null + eval "make clean" + eval "make all EXTRA_CFLAGS=\" $TMP_CFLAGS \" ARCH=$ARCH " >>$CMP_LOG 2>>$CMP_LOG + if [ $? -eq 0 ]; then + echo -e "Done" + echo " " + else + echo -e "Failed" + cat $CMP_LOG + fi + + \cp -f wanpipe_fr.o $lhome/wanpipe_fr.o + fr_file=wanpipe_fr.o + cd $lhome + + else + fr_file=wanpipe_fr.gcc$GCC_VER.$ARCH$REGPARM_OPT.o + if [ ! -e $fr_file ]; then + echo "Warning: FR Binary $fr_filenot found!" + echo "Using wanpipe_fr.gcc3.i386.o" + fr_file=wanpipe_fr.gcc3.i386.o + fi + \cp $fr_file wanpipe_fr.o + fi + LIP_BIN_OBJS=$LIP_BIN_OBJS"wanpipe_fr.o " + fi + + if [ $PPP_PROT = "YES" ] || [ $CHDLC_PROT = "YES" ]; then + if [ -e $DRIVER_UPDATE_DIR/sppp ]; then + echo -n "Compiling PPP and CHDLC sources..." + lhome=`pwd` + cd $DRIVER_UPDATE_DIR/sppp + eval "rm -f *.o" >/dev/null 2>/dev/null + eval "make clean" + eval "make all EXTRA_CFLAGS=\" $TMP_CFLAGS -Iinclude \" ARCH=$ARCH " >>$CMP_LOG 2>>$CMP_LOG + if [ $? -eq 0 ]; then + echo -e "Done" + echo " " + else + echo -e "Failed" + cat $CMP_LOG + fi + \cp -f wanpipe_sppp.o $lhome/wanpipe_sppp.o + cd $lhome + + sppp_file=wanpipe_sppp.o + else + sppp_file=wanpipe_sppp.gcc$GCC_VER.$ARCH$REGPARM_OPT.o + if [ ! -e $sppp_file ]; then + echo "Warning: SPPP Binary $sppp_file not found!" + echo "Using wanpipe_sppp.gcc3.i386.o" + sppp_file=wanpipe_sppp.gcc3.i386.o + fi + \cp $sppp_file wanpipe_sppp.o + fi + LIP_BIN_OBJS=$LIP_BIN_OBJS"wanpipe_sppp.o " + fi + + if [ $ATM_PROT = "YES" ]; then + lip_atm_file=wanpipe_lip_atm.gcc$GCC_VER.$ARCH$REGPARM_OPT.o + if [ ! -e $lip_atm_file ]; then + echo "Warning: LIP ATM Binary $lip_atm_file not found!" + echo "Using wanpipe_lip_atm.gcc3.i386.o" + lip_atm_file=wanpipe_lip_atm.gcc3.i386.o + fi + cp $lip_atm_file wanpipe_lip_atm.o + LIP_BIN_OBJS=$LIP_BIN_OBJS"wanpipe_lip_atm.o " + fi + + if [ $LAPB_PROT = "YES" ]; then + lapb_file=wanpipe_lapb.gcc$GCC_VER.$ARCH$REGPARM_OPT.o + if [ ! -e $lapb_file ]; then + echo "Warning: FR Binary $lapb_file not found!" + echo "Using wanpipe_lapb.gcc3.i386.o" + lapb_file=wanpipe_lapb.gcc3.i386.o + fi + cp $lapb_file wanpipe_lapb.o + LIP_BIN_OBJS=$LIP_BIN_OBJS"wanpipe_lapb.o " + fi + + if [ $XDLC_PROT = "YES" ]; then + xdlc_file=wanpipe_xdlc.gcc$GCC_VER.$ARCH$REGPARM_OPT.o + if [ ! -e $xdlc_file ]; then + echo "Warning: FR Binary $xdlc_file not found!" + echo "Using wanpipe_xdlc.gcc3.i386.o" + xdlc_file=wanpipe_xdlc.gcc3.i386.o + fi + cp $xdlc_file wanpipe_xdlc.o + LIP_BIN_OBJS=$LIP_BIN_OBJS"wanpipe_xdlc.o " + fi + + if [ $XMTP2_PROT = "YES" ]; then + + SCTP_LOAD=YES + + xmtp2_file=wanpipe_xmtp2.gcc$GCC_VER.$ARCH$REGPARM_OPT.o + if [ ! -e $xmtp2_file ]; then + echo "Warning: FR Binary $xmtp2_file not found!" + echo "Using wanpipe_xmtp2.gcc3.i386.o" + xmtp2_file=wanpipe_xmtp2.gcc3.i386.o + fi + cp $xmtp2_file wanpipe_xmtp2.o + LIP_BIN_OBJS=$LIP_BIN_OBJS"wanpipe_xmtp2.o " + + if [ -d xmtp2km ]; then + rm -rf xmtp2km + fi + + \cp -rf $DRIVER_UPDATE_DIR/src/xmtp2km . + cd xmtp2km + cp ../Makefile . + ln -s ../mod mod + ln -s ../tmp tmp + + xmtp2km_file=xmtp2km.gcc$GCC_VER.$ARCH$REGPARM_OPT.o + if [ ! -e bin/$xmtp2km_file ]; then + echo "Warning: XMTP2KM Binary $xmtp2km_file not found!" + xmtp2km_file=xmtp2km.gcc3.i386.o + echo "Using $xmtp2km_file" + fi + + XMTP2KM_OBJ="main2_6 fwmsg" + + build_kernel_module xmtp2km "$XMTP2KM_OBJ" "-D__XMTP2__" "bin/$xmtp2km_file" + + if [ -e xmtp2km.ko ]; then + \cp -f xmtp2km.ko ../mod + fi + + cd .. + fi + + + LIP_DEFINES="-DWANLIP_DRIVER -DWPLIP_TTY_SUPPORT" + + lip_src_mods="wanpipe_lip_iface wanpipe_lip_bh wanpipe_lip_prot wanpipe_lip_netdev wanpipe_lip_sub wanpipe_lip_tty wanpipe_abstr wanpipe_linux_iface " + if [ $KATM_PROT = "YES" ]; then + lip_src_mods=$lip_src_mods" wanpipe_katm_iface wanpipe_katm_sub" + fi + + build_kernel_module wanpipe_lip "$lip_src_mods" "$LIP_DEFINES" "$LIP_BIN_OBJS" + + + if [ $FR_PROT = "YES" ]; then + echo "FR compiled for GCC Ver=$GCC_VER Arch=$ARCH File:$fr_file" + echo + fi + if [ $PPP_PROT = "YES" ] || [ $CHDLC_PROT = "YES" ]; then + echo "PPP/CHDLC compiled for GCC Ver=$GCC_VER Arch=$ARCH File:$sppp_file" + echo + fi + if [ $LAPB_PROT = "YES" ]; then + echo "Lapb compiled for GCC Ver=$GCC_VER Arch=$ARCH File:$lapb_file" + echo + fi + if [ $XDLC_PROT = "YES" ]; then + echo "Xdlc compiled for GCC Ver=$GCC_VER Arch=$ARCH File:$xdlc_file" + echo + fi + if [ $ATM_PROT = "YES" ]; then + echo "ATM compiled for GCC Ver=$GCC_VER Arch=$ARCH File:$lip_atm_file" + echo + fi + if [ $XMTP2_PROT = "YES" ]; then + echo "XMTP2 compiled for GCC Ver=$GCC_VER Arch=$ARCH File:$xmtp2_file" + echo + fi + fi + + + if [ "$ADSL_PROT" = "YES" ]; then + echo "ADSL binary compiled for GCC Ver=$GCC_VER Arch=$ARCH File:$adsl_file" + echo + fi + + if [ "$ATM_PROT" = "YES" ]; then + echo "ATM binary compiled for GCC Ver=$GCC_VER Arch=$ARCH File:$atm_file" + echo + fi + + if [ "$ECHO_MASTER_PROT" = "YES" ]; then + echo "TDMV Echo Detection (EDAC) binary compiled for GCC Ver=$GCC_VER Arch=$ARCH File:$echo_file" + echo + fi + + + echo -n "Linking Wanpipe Driver and protocols ..." + + #Link in appropriate protocols as needed. + WANPIPE_OBJS=$WANPIPE_OBJS"sdlamain wanpipe_tdm_api wanpipe_codec wanpipe_codec_law " + build_kernel_module wanpipe "$WANPIPE_OBJS" "$WANPIPE_EXTRA_CFLAGS" "$WANPIPE_BIN_OBJS" + + + \cp -f *.ko mod/ > /dev/null 2> /dev/null + + MEXT=o + if [ $KERN_VER -eq 26 ]; then + MEXT=ko + fi + + if [ $? -eq 0 ]; then + echo -e "Done.\n" + else + echo -e "Failed!\n" + return 1 + fi + + update_redhat_as 1 + update_fedora2 1 + + wp_comp_err=0; + if [ ! -e mod/sdladrv.$MEXT ]; then + echo "Compilation Error: Module sdladrv.$MEXT not found!" + wp_comp_err=1; + fi + if [ ! -e mod/wanpipe.$MEXT ]; then + echo "Compilation Error: Module mod/wanpipe.$MEXT not found!" + wp_comp_err=1; + fi + if [ ! -e mod/wanrouter.$MEXT ]; then + echo "Compilation Error: Module mod/wanrouter.$MEXT not found!" + wp_comp_err=1; + fi + if [ ! -e mod/af_wanpipe.$MEXT ]; then + echo "Compilation Error: Module mod/af_wanpipe.$MEXT not found!" + wp_comp_err=1; + fi + if [ "$LIP_PROT" = "YES" ] && [ ! -e mod/wanpipe_lip.$MEXT ]; then + echo "Compilation Error: Module mod/wanpipe_lip.$MEXT not found!" + wp_comp_err=1; + fi + + if [ "$XMTP2_PROT" = "YES" ] && [ ! -e mod/xmtp2km.$MEXT ]; then + echo "Compilation Error: Module mod/xmtp2km.$MEXT not found!" + wp_comp_err=1; + fi + + + + if [ $wp_comp_err -eq 1 ]; then + echo + echo "Wanpipe drivers failed to compile" + echo "Please review the above error messages" + echo "and/or contact Sangoma Tech Support." + echo + return 1 + fi + + #Copy the newly compiled modules into the /lib/modules directory. + + echo -n "Updating Kernel Modules ..." + + if [ $KERN_VER -eq 24 ] || [ $KERN_VER -eq 26 ]; then + + eval "\rm -f $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/sdladrv.$MEXT* > /dev/null 2> /dev/null" + eval "\rm -f $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe.$MEXT* > /dev/null 2> /dev/null" + eval "\rm -f $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_syncppp.$MEXT* > /dev/null 2> /dev/null" + + eval "\rm -f $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wan_aften.$MEXT* > /dev/null 2> /dev/null" + eval "\rm -f $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wanrouter.$MEXT* > /dev/null 2> /dev/null" + eval "\rm -f $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/af_wanpipe.$MEXT* > /dev/null 2> /dev/null" + eval "\rm -f $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wanpipe_lip.$MEXT* > /dev/null 2> /dev/null" + + install -D -m 644 mod/sdladrv.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/sdladrv.$MEXT + install -D -m 644 mod/wanpipe.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe.$MEXT + install -D -m 644 mod/wanrouter.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wanrouter.$MEXT + install -D -m 644 mod/af_wanpipe.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/af_wanpipe.$MEXT + + if [ $GZ_MODULES ] && [ $GZ_MODULES=YES ]; then + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/sdladrv.$MEXT" | xargs gzip -f9 + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe.$MEXT" | xargs gzip -f9 + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wanrouter.$MEXT" | xargs gzip -f9 + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/af_wanpipe.$MEXT" | xargs gzip -f9 + fi + + if [ -f mod/wanpipe_syncppp.$MEXT ]; then + install -D -m 644 mod/wanpipe_syncppp.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_syncppp.$MEXT + if [ $GZ_MODULES ] && [ $GZ_MODULES=YES ]; then + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_syncppp.$MEXT" | xargs gzip -f9 + fi + fi + + if [ -f mod/wan_aften.$MEXT ]; then + install -D -m 644 mod/wan_aften.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wan_aften.$MEXT + if [ $GZ_MODULES ] && [ $GZ_MODULES=YES ]; then + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wan_aften.$MEXT" | xargs gzip -f9 + fi + fi + + + if [ -d "$DRIVER_UPDATE_DIR/wanec" ]; then + install -D -m 644 $DRIVER_UPDATE_DIR/wanec/wanec.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wanec.$MEXT + if [ $GZ_MODULES ] && [ $GZ_MODULES=YES ]; then + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wanec.$MEXT" | xargs gzip -f9 + fi + fi + + if [ -f mod/wanpipe_x25.$MEXT ]; then + install -D -m 644 mod/wanpipe_x25.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_x25.$MEXT + if [ $GZ_MODULES ] && [ $GZ_MODULES=YES ]; then + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_x25.$MEXT" |xargs gzip -f9 + fi + fi + if [ -f mod/wanpipe_lapb.$MEXT ]; then + install -D -m 644 mod/wanpipe_lapb.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_lapb.$MEXT + if [ $GZ_MODULES ] && [ $GZ_MODULES=YES ]; then + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_lapb.$MEXT" |xargs gzip -f9 + fi + fi + if [ -f mod/wanpipe_dsp.$MEXT ]; then + install -D -m 644 mod/wanpipe_dsp.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_dsp.$MEXT + if [ $GZ_MODULES ] && [ $GZ_MODULES=YES ]; then + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_dsp.$MEXT" |xargs gzip -f9 + fi + fi + + if [ -f mod/xmtp2km.$MEXT ]; then + install -D -m 644 mod/xmtp2km.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/xmtp2km.$MEXT + if [ $GZ_MODULES ] && [ $GZ_MODULES=YES ]; then + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/xmtp2km.$MEXT" |xargs gzip -f9 + + fi + fi + + + if [ -f mod/wanpipe_lip.$MEXT ]; then + install -D -m 644 mod/wanpipe_lip.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wanpipe_lip.$MEXT + if [ $GZ_MODULES ] && [ $GZ_MODULES=YES ]; then + echo "$ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wanpipe_lip.$MEXT" |xargs gzip -f9 + fi + fi + + + cat < $CMP_INSTALL +#!/bin/sh + + mv *.ko mod/ > /dev/null 2> /dev/null + + install -D -m 644 mod/sdladrv.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/sdladrv.$MEXT + install -D -m 644 mod/wanpipe.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe.$MEXT + install -D -m 644 mod/wanrouter.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wanrouter.$MEXT + install -D -m 644 mod/af_wanpipe.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/af_wanpipe.$MEXT + + + if [ -f mod/wanpipe_syncppp.$MEXT ]; then + install -D -m 644 mod/wanpipe_syncppp.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_syncppp.$MEXT + fi + + if [ -f mod/wan_aften.$MEXT ]; then + install -D -m 644 mod/wan_aften.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wan_aften.$MEXT + fi + + if [ -f mod/wanpipe_lip.$MEXT ]; then + install -D -m 644 mod/wanpipe_lip.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/net/wanrouter/wanpipe_lip.$MEXT + fi + + if [ -f mod/wanpipe_x25.$MEXT ]; then + install -D -m 644 mod/wanpipe_x25.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_x25.$MEXT + fi + if [ -f mod/wanpipe_lapb.$MEXT ]; then + install -D -m 644 mod/wanpipe_lapb.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_lapb.$MEXT + fi + if [ -f mod/wanpipe_dsp.$MEXT ]; then + install -D -m 644 mod/wanpipe_dsp.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/wanpipe_dsp.$MEXT + fi + + if [ -f mod/xmtp2km.$MEXT ]; then + install -D -m 644 mod/xmtp2km.$MEXT $ROOT/lib/modules/$KERNEL_VERSION/kernel/drivers/net/wan/xmtp2km.$MEXT + fi + + echo + echo "Modules installed in $ROOT/lib/modules/$KERNEL_VERSION: OK" + echo + +ENDOFTEXT + + chmod 755 $CMP_INSTALL + + cat < .clean.$$ +#!/bin/sh + +rm -f *.ko +rm -f tmp/*.*o +rm -f mod/*.*o + +echo "Clean Done" + +ENDOFTEXT + + cat .clean.$$ ../samples/clean.sh > $CMP_CLEAN + + chmod 755 $CMP_CLEAN + + else + install -D -m 644 mod/sdladrv.o $ROOT/lib/modules/$KERNEL_VERSION/net/sdladrv.o + install -D -m 644 mod/wanpipe.o $ROOT/lib/modules/$KERNEL_VERSION/net/wanpipe.o + install -D -m 644 mod/wanrouter.o $ROOT/lib/modules/$KERNEL_VERSION/misc/wanrouter.o + install -D -m 644 mod/af_wanpipe.o $ROOT/lib/modules/$KERNEL_VERSION/misc/af_wanpipe.o + if [ -f mod/wanpipe_syncppp.o ]; then + install -D -m 644 mod/wanpipe_syncppp.o $ROOT/lib/modules/$KERNEL_VERSION/net/wanpipe_syncppp.o + fi + + if [ -f mod/wan_aften.o ]; then + install -D -m 644 mod/wan_aften.o $ROOT/lib/modules/$KERNEL_VERSION/misc/wan_aften.o + fi + + if [ -f mod/wanpipe_lip.o ]; then + install -D -m 644 mod/wanpipe_lip.o $ROOT/lib/modules/$KERNEL_VERSION/misc/wanpipe_lip.o + fi + + fi + + if [ $? -eq 0 ]; then + echo -e "Done.\n" + else + echo -e "Failed!\n" + return 1 + fi + +# End of !LITE + fi + + if test -z $ROOT; then + #Check dependencies. + eval "depmod -a 2> $PROD_HOME/tmp.$$" + if [ -f $PROD_HOME/tmp.$$ ]; then + eval "grep wanpipe -i $PROD_HOME/tmp.$$ 2> /dev/null" + rc1=$? + eval "grep sdladrv -i $PROD_HOME/tmp.$$ 2> /dev/null" + rc2=$? + eval "grep wanrouter -i $PROD_HOME/tmp.$$ 2> /dev/null" + rc3=$? + eval "grep af_wanpipe -i $PROD_HOME/tmp.$$ 2> /dev/null" + rc4=$? + + if [ $rc1 -eq 0 ] || [ $rc2 -eq 0 ] || [ $rc3 -eq 0 ] || [ $rc4 -eq 0 ]; then + echo "WARNING: Module dependencies failed!" + echo "" + echo " The MODULE_VERSIONS in the current linux source" + echo " are different from the current linux image." + echo " Or the MODULE_VERSIONS have been turned off in" + echo " the current linux source." + echo + echo " In this case, take this messages as a WARNING, and" + echo " proceed with ${DISTR_NAME} installation." + echo " After the installation is complete, run" + echo + echo " wanrouter hwprobe" + echo + echo " to test ${DISTR_NAME} kernel modules!." + echo " If the hardware probe is successfull ignore the" + echo " above message, otherwise call Sangoma Tech Support" + echo "" + rm -f $PROD_HOME/tmp.$$ + if [ -d "$DRIVER_TMP_DIR" ]; then + rm -rf $DRIVER_TMP_DIR + fi + pause + fi + rm -f $PROD_HOME/tmp.$$ + fi + fi + + #OPTIONAL + if [ -d "$DRIVER_TMP_DIR" ] && [ "$DEVEL_DEBUG" = "NO" ]; then + rm -rf $DRIVER_TMP_DIR + fi + + getyn "Visually Confirm that driver compilation was successful!" + if [ $? -eq 0 ]; then + echo "Compilation Successful." + DRIVERS_COMPILED=yes + else + echo "Compilation Failed!" + return 1 + fi + + return 0 +} + +function install_chan_woomera() +{ + AST_MODULES=chan_woomera.c + if test $NONINTERACTIVE; then + ast_src_dir=/usr/src/asterisk + fi + + cd $PROD_HOME/$SSMG_DIR + cd sangoma_mgd.trunk + + CUR_PWD=`pwd` + + if [ "$ast_src_dir" = "" ]; then + echo + echo "Please Specify Asterisk Source Directory" + echo "Default [/usr/src/asterisk] just press " + echo + echo -n "Asterisk Source: " + read ast_src_dir + + if [ "$ast_src_dir" = "" ]; then + ast_src_dir="/usr/src/asterisk" + fi + fi + + echo + echo + echo "Installing chan_woomera in: $ast_src_dir" + echo + + if [ ! -d $ast_src_dir ]; then + echo + echo "Directory $ast_src_dir not found!" + echo + return 1 + fi + + if [ ! -e $ast_src_dir/contrib/scripts/astxs ]; then + echo + echo "Invalid asterisk source in $ast_src_dir" + echo + return 1 + fi + + + eval "cp -f g711.h $ast_src_dir/" + eval "cp -f $AST_MODULES $ast_src_dir/" + cd $ast_src_dir + + for mod in $AST_MODULES + do + echo "Installing: $mod" + eval "perl ./contrib/scripts/astxs -install $mod > /dev/null" + if [ $? -ne 0 ]; then + echo + echo "Error: Failed to install $mod module!" + install_failures=$install_failures"$mod " + else + echo "Done" + fi + done + + cd $CUR_PWD + + if [ "$install_failures" = "" ]; then + echo + echo "Installatoin Complete" + echo + else + echo + echo "-------------------------------------" + echo + echo "There was an ERROR in asterisk modules installation" + echo "Following modules failed to install:" + echo -e "\t$install_failures" + echo + echo + + return 1 + fi + + return 0 +} + +function install_ssmg () +{ + if [ "$SSMG" != "YES" ]; then + return 0; + fi + + cd $PROD_HOME/$SSMG_DIR + + banner + + echo "Installing LibSangoma Library..." + + cd libsangoma.trunk + eval "./configure; make clean; make; make install" > /dev/null + if [ $? -ne 0 ]; then + echo "FAILED" + return 1 + fi + + if [ -d /etc/ld.so.conf.d ]; then + \cp -f libsangoma.so.conf /etc/ld.so.conf.d/ + eval "ldconfig" + elif [ -f /etc/ld.so.conf ]; then + cat /etc/ld.so.conf libsangoma.so.conf > ldconf.$$ + mv ldconf.$$ /etc/ld.so.conf + eval "ldconfig" + else + echo "Warning: LD Conf files not found in /etc directory" + echo "Please add /usr/local/lib to the LD_LIBRARY_PATH" + echo + pause + fi + + echo "Installing LibSangoma Library...DONE" + echo + + cd $PROD_HOME/$SSMG_DIR + cd sangoma_mgd.trunk + + echo "Installing Sangoma Media Gateway Daemon..." + cd lib/libteletone/ + eval "./configure; make clean; make; make install " > /dev/null + if [ $? -ne 0 ]; then + echo "FAILED" + return 1 + fi + eval "ldconfig" + + cd $PROD_HOME/$SSMG_DIR + +# Let smg install script install SMG components +#======================================================= + +# cd sangoma_mgd.trunk +# +# eval "make clean > /dev/null; make > /dev/null " +# if [ $? -ne 0 ]; then +# echo "FAILED" +# return 1 +# fi +# eval "make install > /dev/null " +# +# echo "Installing Sangoma Media Gateway Daemon...DONE" + +# eval "type asterisk > /dev/null 2> /dev/null" +# if [ $? -ne 0 ]; then +# echo "Error: Asterisk not installed!" +# echo "Please install Asterisk first then retry SSMG installation!" +# return 1 +# fi + +# echo +# echo "Installing Chan Woomera into Asterisk..." +# echo +# install_chan_woomera +# if [ $? -ne 0 ]; then +# echo "Error: Failed to install chan_woomera into Asterisk!" +# echo "Check that Asterisk is installed or Call Sangoma Tech Support" +# echo +# return 1 +# fi +#========================================================= + + cd $PROD_HOME/$SSMG_DIR + cd sangoma_mgd.trunk + + if [ ! -f /etc/asterisk/woomera.conf ]; then + cp woomera.conf /etc/asterisk + fi + + echo "Installing Chan Woomera into Asterisk...DONE" + echo + + if [ ! -f /usr/sbin/smgss7_ctrl ]; then + cp smgss7_ctrl /usr/sbin/ + fi + + getyn "Add Woomera config in Asterisk Extensions and Iax Conf" + if [ $? -ne 0 ]; then + return 0; + fi + + if [ -f /etc/asterisk/extensions.conf ]; then + eval "grep -i woomera /etc/asterisk/extensions.conf 2> /dev/null > /dev/null" + if [ $? -ne 0 ]; then + cat /etc/asterisk/extensions.conf ./conf/woomera_ext.conf > conf.$$ + mv conf.$$ /etc/asterisk/extensions.conf + echo "Asterisk extensions.conf file updated with woomera config" + else + echo "Asterisk extensions.conf already updated" + + fi + else + echo "Warning: Asterisk extensions.conf file not found!" + fi + + if [ -f /etc/asterisk/iax.conf ]; then + eval "grep -i ss7 /etc/asterisk/iax.conf 2> /dev/null > /dev/null" + if [ $? -ne 0 ]; then + cat /etc/asterisk/iax.conf ./conf/woomera_iax.conf > conf.$$ + mv conf.$$ /etc/asterisk/iax.conf + echo "Asterisk iax.conf file updated with ss7 guest config" + else + echo "Asterisk iax.conf already updated" + fi + else + echo "Warning: Asterisk extensions.conf file not found!" + fi + + pause + + return 0 +} + +function install_all () +{ + echo "Installing ${DISTR_NAME} Files ... !" + + echo "Installing ${DISTR_NAME} Utilities in $ROOT/usr/sbin" + + cd $PROD_HOME/util + make install WAN_VIRTUAL=$ROOT > /dev/null 2> /dev/null + + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + cd $PROD_HOME + \cp -rf samples $ROOT/etc/wanpipe + install -D -m 755 $PROD_HOME/scripts/wanlite $ROOT/usr/sbin/wanlite + pause + return 0 + fi + + install -D -m 755 $WANROUTER_STARTUP_SMPL $ROOT/$WANROUTER_STARTUP + + cd $PROD_HOME/util/misc + make install WAN_VIRTUAL=$ROOT > /dev/null 2> /dev/null + + echo "Installing wanrouter.rc in $ROOT/etc/wanpipe" + cd $PROD_HOME + install -D -m 644 wanrouter.rc $ROOT/etc/wanpipe/wanrouter.rc + + echo "Installing wanpipe libraries in $ROOT/etc/wanpipe" + + \mkdir -p $ROOT/etc/wanpipe/lib/ + \cp -f $PROD_HOME/util/wancfg_legacy/lib/* $ROOT/etc/wanpipe/lib/ + + echo "Installing firmware in $ROOT/etc/wanpipe/firmware" + \cp -rf firmware $ROOT/etc/wanpipe/ + + if [ ! -f $ROOT/etc/wanpipe/interfaces ]; then + \mkdir -p $ROOT/etc/wanpipe/interfaces + fi + + echo "Installing documentation in $ROOT/usr/share/doc/wanpipe" + if [ ! -d $ROOT/usr/share/doc/wanpipe ]; then + \mkdir -p $ROOT/usr/share/doc/wanpipe + fi + \cp -f doc/* $ROOT/usr/share/doc/wanpipe + \cp -f README* $ROOT/usr/share/doc/wanpipe + + echo "Installing sample api code in $ROOT/etc/wanpipe/api" + \cp -rf api $ROOT/etc/wanpipe + \cp -rf samples $ROOT/etc/wanpipe + + + if [ ! -d $ROOT/etc/wanpipe/scripts ]; then + \mkdir -p $ROOT/etc/wanpipe/scripts + fi + + echo "Installing driver headers in $ROOT/etc/wanpipe/api/include/linux" + if [ ! -d $ROOT/etc/wanpipe/api/include/linux ]; then + \mkdir -p $ROOT/etc/wanpipe/api/include/linux + fi + + + cd $PROD_HOME + if [ -d wan_ec ]; then + cp -rf wan_ec $ROOT/etc/wanpipe + echo "Installing Hardware Echo Cancel Utilites" + cd util/wanec_client + make install WAN_VIRTUAL=$ROOT > /dev/null 2> /dev/null + cd $PROD_HOME + + if [ ! -e /dev/wanec ]; then + mknod /dev/wanec c 242 0 + fi + else + echo "Hardware Echo Cancel Utilites Not Installed" + fi + cd $PROD_HOME + + + if [ ! -f $ROOT/etc/wanpipe/api/include/linux/ ]; then + \mkdir -p $ROOT/etc/wanpipe/api/include/linux/ + fi + + \cp -f $DRIVER_UPDATE_DIR/include/*.* $ROOT/etc/wanpipe/api/include/linux/ + + pause + return 0 +} + +function uninstall_all () +{ + echo "Uninstalling ${DISTR_NAME} Binaries!\n" + + cd $PROD_HOME/util + make uninstall WAN_VIRTUAL=$ROOT > /dev/null 2> /dev/null + + if [ "$PKG_NAME" = "wanpipe-lite" ]; then + pause + return 0; + fi + + cd $PROD_HOME/util/misc + make uninstall WAN_VIRTUAL=$ROOT > /dev/null 2> /dev/null + + cd $PROD_HOME + rm -f $ROOT/usr/sbin/wp_pppconfig + rm -rf $ROOT/usr/doc/wanpipe + rm -rf $ROOT/etc/wanpipe + + pause + return 0 +} + +function enable_custom_protocols () +{ + local level=$1 + + if test $NONINTERACTIVE; then + return 0 + fi + + if [ "$level" != "" ]; then + enable_protocols $DEFAULT_PROTOCOLS + fi + + while [ 1 ]; + do + + banner + + if [ "$level" = "" ]; then + cat <]: " + + read response + + if [ "$response" = "EXIT" ]; then + return 0; + fi + + if [ "$response" = "Q" ]; then + return 0; + fi + + if [ "$response" = "q" ]; then + return 0; + fi + + echo "$response" | grep "DEF" > /dev/null + if [ $? -eq 0 ]; then + enable_protocols $DEFAULT_PROTOCOLS + fi + + echo "$response" | grep "^API" > /dev/null + if [ $? -eq 0 ]; then + enable_protocols $API_PROTOCOLS + fi + + echo "$response" | grep "ALL" > /dev/null + if [ $? -eq 0 ]; then + enable_protocols $DEFAULT_PROTOCOLS + enable_protocols $API_PROTOCOLS + fi + + echo "$response" | grep "NONE" > /dev/null + if [ $? -eq 0 ]; then + init_all_protocols + fi + + echo "$response" | grep "TDM" > /dev/null + if [ $? -eq 0 ]; then + enable_protocols $response + enable_protocols AFT_TE1 + fi + + if [ $response != "DEF" ] && + [ $response != "API" ] && + [ $response != "ALL" ] && + [ $response != "NONE" ] && + [ $response != "TDM" ]; then + + enable_protocols $response + if [ $? -ne 0 ]; then + pause + fi + fi + + done +} + +search_and_replace() +{ + local input_file_name=$1 + local output_file_name=$2 + local search_str="$3" + local replace_str="$4" + local tmp_file=output.tmp + + #echo "input_file_name:$input_file_name" + #echo "output_file_name:$output_file_name" + #echo "search_str:$search_str" + #echo "replace_str:$replace_str" + + eval "grep '$search_str' $input_file_name > /dev/null 2> /dev/null" + + if [ $? -ne 0 ]; then + echo "Did NOT find the seached str:$search_str" + return 1 + else + #echo "Found the seached str" + eval "sed 's/'\"$search_str\"'/'\"$replace_str\"'/' $input_file_name > $tmp_file" + mv $tmp_file $output_file_name + fi + + return $? +} +function tdmv_get_zaptel_path () +{ + + if [ $ZAPTEL_PATH_OP != "YES" ]; then + find_zap_dirs + fi + +if [ 0 ]; then + if [ $ZAPTEL_PATH_OP != "YES" ]; then + echo + echo -e "\nPlease specify absolute path to Zaptel source directory" + echo -e "\n[default:$ZAPTEL_INSTALL_DIR]\n" + echo -n " " + if [ ! -d $ZAPTEL_INSTALL_DIR ]; then + echo -e "Warning: $ZAPTEL_INSTALL_DIR does not exist\n" + fi + if test -z $NONINTERACTIVE; then + read response + + [ $response ] && { + ZAPTEL_INSTALL_DIR=$response + } + fi + fi + if [ ! -f $ZAPTEL_INSTALL_DIR/zaptel.h ]; then + echo " Zaptel source not found in $ZAPTEL_INSTALL_DIR" + ZAPTEL_INSTALL_DIR="/usr/src/zaptel" + if test $NONINTERACTIVE; then + return 1 + else + getyn " Press Y to specify another Zaptel source directory, N to exit" + if [ $? -ne 0 ]; then + exit 1; + fi + tdmv_get_zaptel_path + fi + fi +fi + #zaptel.c renamed to zaptel-base.c in zaptel v1.2.13 and later + if [ -e $ZAPTEL_INSTALL_DIR/zaptel-base.c ]; then + ZAPTEL_C_FILE="zaptel-base.c"; + fi + return 0; +} + +function tdmv_apply_zaptel_dchan_patch_old () +{ + local rc + ZAPTEL_PATCH_FILE=zaptel.patch + + + if [ ! -e $PROD_HOME/zaptel ]; then + echo "Error: Zaptel Patch Directory Not Found!" + return 1; + fi + + lhome=`pwd` + + cd $ZAPTEL_INSTALL_DIR + + + if [ ! -e CVS ]; then + ZAPTEL_PATCH_FILE=zaptel-1.0.9.patch + fi + + + if [ ! -f $PROD_HOME/zaptel/$ZAPTEL_PATCH_FILE ];then + echo "Error: Zaptel Patch File zaptel/$ZAPTEL_PATCH_FILE Not Found!" + cd $lhome + return 1; + fi + + + eval "grep \"DCHAN_TX\" $ZAPTEL_C_FILE > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + + eval "grep \"ZT_DCHAN_TX_V2\" $ZAPTEL_C_FILE > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "Zaptel DCHAN patch V.02 already installed" + cd $lhome + return 0 + else + echo "ERROR: Old Zaptel DCHAN patch detected in $ZAPTEL_INSTALL_DIR" + echo + echo " Please install a fresh version of Zaptel source and" + echo " run ./Setup again." + echo + cd $lhome + exit 1 + fi + fi + + cp $PROD_HOME/zaptel/$ZAPTEL_PATCH_FILE zaptel.patch + + eval "patch -p1 < zaptel.patch" + rc=$? + + echo + + if [ $rc -ne 0 ]; then + echo "Zaptel DCHAN Patch Failed" + rc=1 + else + eval "grep \"ZT_DCHAN_TX_V2\" $ZAPTEL_C_FILE > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "Zaptel Source Patched with DCHAN V.02 Successfully" + rc=0 + else + echo "Zaptel DCHAN V.02 Patch Failed" + rc=1 + fi + fi + + cd $lhome + + return $rc +} +function tdmv_apply_zaptel_chunk_patch () { + lhome=`pwd` + TEMP=tmp + cd $ZAPTEL_INSTALL_DIR + echo "Applying Zaptel Chunk patch..." + echo " " + #modify zaptel.h + eval "cat zaptel.h | sed '/^#define ZT_CHUNKSIZE/c\#define ZT_CHUNKSIZE $ZAP_CHUNK' >$TEMP 2>/dev/null" + if [ $? -ne 0 ]; then + echo " Failed to substitute ZT_CHUNKSIZE string in zaptel.h" + exit 1 + else + eval "\mv -f $TEMP zaptel.h" + if [ $? -ne 0 ]; then + echo " Failed to overwrite existing zaptel.h" + exit 1 + else + echo " Zaptel patched for chunk size successfully" + zaptel_modified=1 + fi + fi + + #remove wct4xxp module from Makefile + eval "cat Makefile |sed 's/wct1xxp wct4xxp wcte11xp/wct1xxp wcte11xp/g'>$TEMP 2>/dev/null " + if [ $? -ne 0 ]; then + echo " Failed to remove wct4xxp from Makefile" + exit 1 + else + eval "\mv -f $TEMP Makefile" + if [ $? -ne 0 ]; then + echo " Failed to overwrite existing Makefile" + exit 1 + else + echo " wct4xxp module removed from Makefile successfully" + zaptel_modified=1 + fi + fi + + eval "cat Makefile |sed 's/^SUBDIR_MODULES:=.*//g'>$TEMP 2>/dev/null " + if [ $? -ne 0 ]; then + echo " Failed to remove wct4xxp from Makefile" + exit 1 + else + eval "\mv -f $TEMP Makefile" + if [ $? -ne 0 ]; then + echo " Failed to overwrite existing Makefile" + exit 1 + else + echo " wct4xxp module removed from Makefile successfully" + zaptel_modified=1 + fi + fi + + if [ -f Makefile.kernel26 ]; then + eval "cat Makefile.kernel26 | sed 's/^obj-m.*+=.*wct4xx.*//g'>$TEMP 2>/dev/null " + if [ $? -ne 0 ]; then + echo " Failed to remove wct4xxp from Makefile.kernel26" + exit 1 + + else + eval "\mv -f $TEMP Makefile.kernel26" + echo " wct4xxp module removed from Makefile.kernel26 successfully" + zaptel_modified=1 + fi + fi + + cd $lhome + return 0; +} + +function tdmv_apply_zaptel_echo_debug_patch () +{ + local rc + if [ ! -e $PROD_HOME/zaptel ]; then + echo "Error: Zaptel Patch Directory Not Found!" + return 1; + fi + + if [ ! -f $PROD_HOME/zaptel/$ZAPTEL_C_ECHO_DEBUG_PATCH ]; then + echo "Error: file $ZAPTEL_C_ECHO_DEBUG_PATCH Not Found!" + return 1; + fi + + if [ ! -f $PROD_HOME/zaptel/$ZAPTEL_H_ECHO_DEBUG_PATCH ]; then + echo "Error: file $ZAPTEL_H_ECHO_DEBUG_PATCH Not Found!" + return 1; + fi + + ####################################################################################### + lhome=`pwd` + cd $ZAPTEL_INSTALL_DIR + + #check if some version of the patch is already installed in $ZAPTEL_C_FILE + eval "grep \"GET_ECHO_SPIKE_SAMPLE\" $ZAPTEL_C_FILE > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "Echo Debugging patch for Zaptel already installed in $ZAPTEL_C_FILE." + echo "Consider using fresh (unpatched) Zaptel source." + cd $lhome + return 0 + fi + + #check if some version of the patch is already installed in zaptel.h + eval "grep \"ECHO_SPIKE_SAMPLE_LEN\" zaptel.h > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "Echo Debugging patch for Zaptel already installed in zaptel.h." + echo "Consider using fresh (unpatched) Zaptel source." + cd $lhome + return 0 + fi + + ####################################################################################### + cp $PROD_HOME/zaptel/$ZAPTEL_C_ECHO_DEBUG_PATCH . + + eval "patch $ZAPTEL_C_FILE $ZAPTEL_C_ECHO_DEBUG_PATCH > /dev/null 2> /dev/null" + rc=$? + if [ $rc -ne 0 ]; then + echo "Echo Detection patch for Zaptel Failed (1)" + cd $lhome + return 1 + fi + + ####################################################################################### + eval "search_and_replace zaptel.h zaptel.h \"$ZAPTEL_H_SEARCH_STR\" \"$ZAPTEL_H_ECHO_DEBUG_PATCH_STR\"" + rc=$? + if [ $rc -ne 0 ]; then + echo "Echo Detection patch for Zaptel Failed (2)" + cd $lhome + return 1 + fi + + ####################################################################################### + cp $PROD_HOME/zaptel/$ZAPTEL_H_ECHO_DEBUG_PATCH . + eval "patch zaptel.h $ZAPTEL_H_ECHO_DEBUG_PATCH > /dev/null 2> /dev/null" + rc=$? + echo + if [ $rc -ne 0 ]; then + echo "Echo Detection patch for Zaptel Failed (3)" + cd $lhome + return 1 + fi + ####################################################################################### + echo " Zaptel Source patched with Echo Debugging code Successfully" + zaptel_modified=1 + rc=0 + cd $lhome + return $rc +} + +function tdmv_apply_zaptel_edac_patch () +{ + local rc + + if [ ! -e $PROD_HOME/edac ]; then + echo "Error: Zaptel Patch Directory Not Found!" + return 1; + fi + + if [ ! -f $PROD_HOME/edac/$EDAC_ZAP_PATCH_FILE ]; then + echo "Error: Echo Detection patch file for Zaptel edac/$EDAC_ZAP_PATCH_FILE Not Found!" + return 1; + fi + + lhome=`pwd` + + cd $ZAPTEL_INSTALL_DIR + + #check if some version of the patch is already installed + eval "grep \"SANGOMA_GET_ED_STATE\" $ZAPTEL_C_FILE > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "Echo Detection patch for Zaptel already installed." + echo "Consider using fresh (unpatched) Zaptel source." + cd $lhome + return 0 + fi + + cp $PROD_HOME/edac/$EDAC_ZAP_PATCH_FILE . + + #eval "patch -F 3 -c -d $ZAPTEL_INSTALL_DIR < $EDAC_ZAP_PATCH_FILE" + eval "patch -p1 < $EDAC_ZAP_PATCH_FILE" + rc=$? + + echo + + if [ $rc -ne 0 ]; then + echo "Echo Detection patch for Zaptel Failed" + rc=1 + else + eval "grep \"SANGOMA_GET_ED_STATE\" $ZAPTEL_C_FILE > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "Zaptel Source patched with Echo Detection V1.00 Successfully" + rc=0 + else + echo "Echo Detection and Control patch for Zaptel failed!" + rc=1 + fi + fi + + cd $lhome + zaptel_modified=1 + return $rc +} + +function tdmv_apply_asterisk_edac_patch () +{ + local rc + + tdmv_get_asterisk_source_path + if [ $? -ne 0 ]; then + return 1; + fi + + if [ ! -e $PROD_HOME/edac ]; then + echo "Error: Zaptel Patch Directory Not Found!" + return 1; + fi + + if [ -d $ASTERISK_INSTALL_DIR/CVS ]; then + #We are running Asterisk CVS use the CVS patch + EDAC_ASTERISK_PATCH_FILE=$EDAC_ASTERISK_CVS_PATCH_FILE + fi + + if [ ! -f $PROD_HOME/edac/$EDAC_ASTERISK_PATCH_FILE ]; then + echo "Error: Echo Detection patch file for Asterisk edac/$EDAC_ASTERISK_PATCH_FILE Not Found!" + return 1; + fi + + lhome=`pwd` + + cd $ASTERISK_INSTALL_DIR/channels + + #check if some version of the patch is already installed + eval "grep \"SANGOMA_SPIKE_SAMPLE_LEN\" chan_zap.c > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "Echo Detection patch for Asterisk already installed." + echo "Consider using fresh (unpatched) Asterisk source." + cd $lhome + return 0 + fi + + cd $ASTERISK_INSTALL_DIR + + cp $PROD_HOME/edac/$EDAC_ASTERISK_PATCH_FILE . + + eval "patch -p1 < $EDAC_ASTERISK_PATCH_FILE" + rc=$? + + echo + + if [ $rc -ne 0 ]; then + echo "Echo Detection patch for Asterisk Failed" + rc=1 + else + cd $ASTERISK_INSTALL_DIR/channels + eval "grep \"SANGOMA_SPIKE_SAMPLE_LEN\" chan_zap.c > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + echo "Asterisk Source patched with Echo Detection V1.00 Successfully" + rc=0 + else + echo "Echo Detection and Control patch for Asterisk failed!" + rc=1 + fi + fi + + cd $lhome + + + return $rc +} +function tdmv_compile_zaptel() +{ + lhome=`pwd` + + cd $ZAPTEL_INSTALL_DIR + echo + echo -n " Removing current Zaptel compilation(make clean)..." + if [ -f configure ]; then + eval "./configure >> $PROD_HOME/zaptel_compilation_log 2>> $PROD_HOME/zaptel_compilation_log" + fi + eval "make clean >> $PROD_HOME/zaptel_compilation_log 2>> $PROD_HOME/zaptel_compilation_log" + if [ ! $? -eq 0 ]; then + cat $PROD_HOME/zaptel_compilation_log + echo + echo "Error: Could not remove current Zaptel Compilation" + echo " See $PROD_HOME/zaptel_compilation_log for details" + echo " Contact Sangoma Tech Support" + echo + getyn "Would you like to continue?" + if [ $? -ne 0 ]; then + exit 1 + fi + else + echo "OK" + if [ -e menuselect/mxml ]; then + cd menuselect/mxml + eval "grep \" $ZAPTEL_MENUSELECT_SEARCH_STR\" Makefile.in > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + eval "search_and_replace Makefile.in Makefile.in \"$ZAPTEL_MENUSELECT_SEARCH_STR\" \"$ZAPTEL_MENUSELECT_REMOVE\"" + fi + if [ -e Makefile ]; then + eval "grep \" $ZAPTEL_MENUSELECT_SEARCH_STR\" Makefile > /dev/null 2> /dev/null" + if [ $? -eq 0 ]; then + eval "search_and_replace Makefile Makefile \"$ZAPTEL_MENUSELECT_SEARCH_STR\" \"$ZAPTEL_MENUSELECT_REMOVE\"" + fi + fi + fi + fi + + cd $ZAPTEL_INSTALL_DIR + echo -n " Recompiling/reinstalling Zaptel(make install)..." + eval "make >> $PROD_HOME/zaptel_compilation_log 2>> $PROD_HOME/zaptel_compilation_log" + if [ ! $? -eq 0 ]; then + echo + echo + echo "-------------------------------------------" + cat $PROD_HOME/zaptel_compilation_log + echo "-------------------------------------------" + echo + echo "Error: Zaptel recompilation/reinstallation failed" + echo " See $PROD_HOME/zaptel_compilation_log for details" + echo " Contact Sangoma Tech Support" + echo + getyn "Would you like to continue?" + if [ $? -ne 0 ]; then + exit 1 + fi + else + eval "make install >> $PROD_HOME/zaptel_compilation_log 2>> $PROD_HOME/zaptel_compilation_log" + echo "OK" + echo + fi + cd $lhome +} + +function tdmv_check_zaptel_udev() +{ + echo -n "Checking for UDEV Zaptel compatibility..." + if [ ! -e /etc/udev ]; then + echo + echo " UDEV rules not used " + return 0 + fi + #UDEV rules + if [ ! -f /etc/udev/rules.d/50-udev.rules ]; then + echo " UDEV rules not found/or not used " + return 0 + else + eval "grep \"zapctl\" /etc/udev/rules.d/50-udev.rules > /dev/null" + if [ $? -ne 0 ]; then + echo + getyn " Would you like to add UDEV rules for Zaptel devices ?" + if [ $? -eq 0 ]; then + cp /etc/udev/rules.d/50-udev.rules /etc/udev/rules.d/50-udev.rules.old + # echo "Your original udev rules have been copied to /etc/udev/rules.d/50-udev.rules.old" + + cat $PROD_HOME/samples/udevRulesPatch >> /etc/udev/rules.d/50-udev.rules + eval "grep \"zapctl\" /etc/udev/rules.d/50-udev.rules > /dev/null" + if [ $? -eq 0 ]; then + echo " UDEV rules applied successfully" + else + echo " UDEV rules patch failed" + return 1 + fi + fi + else + echo "OK" + fi + + fi + #UDEV permissions + if [ ! -f /etc/udev/permissions.d/50-udev.permissions ]; then + echo " UDEV permissions not found/or not used " + return 0 + else + eval "cat /etc/udev/permissions.d/50-udev.permissions |grep zap |grep root:root > /dev/null" + if [ $? -ne 0 ]; then + echo + getyn " Would you like to add UDEV permissions for root user ?" + if [ $? -eq 0 ]; then + cp /etc/udev/permissions.d/50-udev.permissions /etc/udev/permissions.d/50-udev.permissions.old + # echo "Your original udev permisions have been copied to /etc/udev/permissions.d/50-udev.permissions.old" + + echo -e "\n# zaptel devices -- for running asterisk as root" >> /etc/udev/permissions.d/50-udev.permissions + echo -e "zap/*:root:root:05700" >> /etc/udev/permissions.d/50-udev.permissions + + eval "cat /etc/udev/permissions.d/50-udev.permissions |grep zap |grep root:root:05700 > /dev/null" + if [ $? -eq 0 ]; then + echo " UDEV root permissions applied successfully" + else + echo " UDEV permissions patch failed" + fi + fi + fi + + eval "cat /etc/udev/permissions.d/50-udev.permissions |grep zap |grep asterisk:asterisk > /dev/null" + if [ $? -ne 0 ]; then + echo + getyn " Would you like to add UDEV Permissions for non-root user?" + if [ $? -eq 0 ]; then + echo -e "\n# zaptel devices -- for running asterisk as a different user " >> /etc/udev/permissions.d/50-udev.permissions + echo -e "zap/*:asterisk:asterisk:660" >> /etc/udev/permissions.d/50-udev.permissions + + eval "cat /etc/udev/permissions.d/50-udev.permissions |grep zap |grep asterisk:asterisk:660 > /dev/null" + if [ $? -eq 0 ]; then + echo " UDEV non-root permissions applied successfully" + else + echo " UDEV permissions patch failed" + fi + fi + fi + fi + echo + pause + echo +} + +function find_zap_dirs_invalid () +{ + echo + echo "Invalid Response $response" + echo + clear + find_zap_dirs "$1" +} + +function find_zap_dirs () +{ + local cnt + local dir + local zapdir_manual=0 + local zapdirs=$1 + + echo + echo "Looking for zaptel directory in /usr/src ..." + echo "-------------------------------------------" + if [ "$zapdirs" = "" ]; then + zapdirs=`find /usr/src -maxdepth 2 -name 'zaptel*' | xargs ` + fi + + unset zapdir_array; + + if [ -f $PROD_HOME/zaptel/zaptel.path ]; then + zapextradir=`cat $PROD_HOME/zaptel/zaptel.path` + fi + + cnt=1 + for dir in $zapdirs + do + if [ ! -d $dir ]; then + continue + fi + + if [ ! -f $dir/zaptel.h ]; then + continue; + fi + + zapdir_array[$cnt]=$dir; + echo "$cnt : $dir " + + cnt=$((cnt+1)) + done + + if [ $cnt -eq 1 ]; then + echo + echo "No zaptel dirs found in /usr/src " + echo "Please use option \"m\" to enter zaptel path" + echo + fi + echo "------------------------------------------ " + + for dir in $zapextradir + do + if [ ! -d $dir ]; then + continue + fi + + if [ ! -f $dir/zaptel.h ]; then + continue; + fi + + zapdir_array[$cnt]=$dir; + echo "$cnt : $dir (entered manually) " + + cnt=$((cnt+1)) + done + + + echo "------------------------------------------ " + echo "m : Enter zaptel path manually" + echo +# echo "d2: Download Latest 1.2" +# echo "d4: Download Latest 1.4" + echo "(ctrl-c to Exit)" + echo -n "Please select working zaptel directory [1-9][m]: " + + response=1 + + if [ -z $NONINTERACTIVE ] || [ $zaptel_auto_install = "YES" ]; then + read response + fi + + if [ "$response" = "" ]; then + find_zap_dirs_invalid "$zapdirs" + elif [ $response = "m" ]; then + echo + echo "Please enter zaptel dir: [Default: $ZAPTEL_DFLT_INSTALL_DIR]" + echo -n "#> " + read response + + if [ "$response" = "" ]; then + ZAPTEL_INSTALL_DIR=$ZAPTEL_DFLT_INSTALL_DIR + else + ZAPTEL_INSTALL_DIR=$response + fi + + zapdir_manual=1 + +# elif [ $response = "q" ]; then +# find_zap_dir_quit=1 +# return 1; + + elif [ $response -gt 0 ] && [ $response -lt $cnt ]; then + ZAPTEL_INSTALL_DIR=${zapdir_array[$response]} + else + find_zap_dirs_invalid "$zapdirs" + fi + + if [ ! -f $ZAPTEL_INSTALL_DIR/zaptel.h ]; then + echo + echo "Error: zaptel.h not found in $ZAPTEL_INSTALL_DIR" + echo + echo + zapdir_manual=0 + pause 1 + clear + find_zap_dirs "$zapdirs" + fi + + if [ $find_zap_dir_quit -eq 1 ] ; then + ZAPTEL_INSTALL_DIR=$ZAPTEL_DFLT_INSTALL_DIR + return 1 + fi + + if [ $zapdir_manual -eq 1 ]; then + eval "grep \"$ZAPTEL_INSTALL_DIR\" $PROD_HOME/zaptel/zaptel.path 2> /dev/null > /dev/null " + if [ $? -ne 0 ]; then + echo "$ZAPTEL_INSTALL_DIR" >> $PROD_HOME/zaptel/zaptel.path + fi + fi + + #echo "GO AUTOMATIC ZAPDIR= $ZAPTEL_INSTALL_DIR" + + ZAPTEL_PATH_OP="YES"; + + #zaptel.c renamed to zaptel-base.c in zaptel v1.2.13 and later + if [ -e $ZAPTEL_INSTALL_DIR/zaptel-base.c ]; then + ZAPTEL_C_FILE="zaptel-base.c"; + fi + + return 0; + +} + +function tdmv_get_asterisk_source_path () +{ + echo + echo -e "\nPlease specify absolute path to Asterisk source directory" + echo -e "\n\t(Press Enter for Default: $ASTERISK_INSTALL_DIR)\n" + if test -z $NONINTERACTIVE; then + read response + + [ $response ] && { + ASTERISK_INSTALL_DIR=$response + } + fi + + if [ ! -f $ASTERISK_INSTALL_DIR/channels/chan_zap.c ]; then + + cat < /dev/null + if [ $? -eq 0 ]; then + if [ $FR_PROT != YES ]; then + echo "Enabling the FR Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_FR " + fi + PROT_MATCH=YES + FR_PROT=YES + fi + + echo "$PROTOCOL" | grep "CHDLC" > /dev/null + if [ $? -eq 0 ]; then + if [ $CHDLC_PROT != YES ]; then + echo "Enabling the CHDLC Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_CHDLC " + fi + PROT_MATCH=YES + CHDLC_PROT=YES + fi + + echo "$PROTOCOL" | grep "PPP" > /dev/null + if [ $? -eq 0 ]; then + if [ $PPP_PROT != YES ]; then + echo "Enabling the PPP Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_PPP " + fi + PROT_MATCH=YES + PPP_PROT=YES + fi + + echo "$PROTOCOL" | grep "X25" > /dev/null + if [ $? -eq 0 ]; then + if [ $X25_PROT != YES ]; then + echo "Enabling the X25 API Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_X25 " + fi + PROT_MATCH=YES + X25_PROT=YES + fi + + echo "$PROTOCOL" | grep "ADSL" > /dev/null + if [ $? -eq 0 ]; then + + if [ -z $ARCH ]; then + ARCH=`uname -m` + fi + + if [ $KERN_VER != 24 ] && [ $KERN_VER != 26 ]; then + cat < /dev/null + if [ $? -eq 0 ]; then + + if [ $KATM_PROT != YES ]; then + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_LIP_KATM " + fi + + KATM_PROT=YES + PROT_MATCH=YES + + #Note that KATM will also match + #ATM protocol, so ATM will automatically be + #enabled. + fi + + + echo "$PROTOCOL" | grep "ATM" > /dev/null + if [ $? -eq 0 ]; then + + if [ $KERN_VER != 24 ] && [ $KERN_VER != 26 ]; then + cat < /dev/null + if [ $? -eq 0 ]; then + if [ $XMTP2_PROT != YES ]; then + echo "Enabling the SS7 XMTP2 Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_XMTP2 " + fi + PROT_MATCH=YES + XMTP2_PROT=YES + SSMG=YES + fi + + echo "$PROTOCOL" | grep "MFR" > /dev/null + if [ $? -eq 0 ]; then + if [ $MFR_PROT != YES ]; then + echo "Enabling the Multi-Port Frame Relay Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_MULTFR " + fi + PROT_MATCH=YES + MFR_PROT=YES + fi + + echo "$PROTOCOL" | grep "MPROT" > /dev/null + if [ $? -eq 0 ]; then + if [ $MPPP_PROT != YES ]; then + echo "Enabling the Multi Protocol Driver" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_MULTPROT " + fi + PROT_MATCH=YES + MPPP_PROT=YES + fi + + echo "$PROTOCOL" | grep "EDU" > /dev/null + if [ $? -eq 0 ]; then + if [ $EDU_PROT != YES ]; then + echo "Enabling the EDU Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_EDU " + fi + EDU_PROT=YES + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "BISYNC" > /dev/null + if [ $? -eq 0 ]; then + if [ $BISYNC_PROT != YES ]; then + echo "Enabling the BISYNC Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_BSC " + fi + BISYNC_PROT=YES + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "BITSTRM" > /dev/null + if [ $? -eq 0 ]; then + if [ $BITSTRM_PROT != YES ]; then + echo "Enabling the BITSTRM Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_BITSTRM " + fi + BITSTRM_PROT=YES + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "BSCSTRM" > /dev/null + if [ $? -eq 0 ]; then + if [ $BSCSTRM_PROT != YES ]; then + echo "Enabling the BSCSTRM Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_BSCSTRM " + fi + BSCSTRM_PROT=YES + PROT_MATCH=YES + fi + + + echo "$PROTOCOL" | grep "SDLC" > /dev/null + if [ $? -eq 0 ]; then + if [ $SDLC_PROT != YES ]; then + echo "Enabling the SDLC Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_SDLC " + fi + SDLC_PROT=YES + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "POS" > /dev/null + if [ $? -eq 0 ]; then + if [ $POS_PROT != YES ]; then + echo "Enabling the POS Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_POS " + fi + POS_PROT=YES + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "ADCCP" > /dev/null + if [ $? -eq 0 ]; then + if [ $ADCCP_PROT != YES ]; then + echo "Enabling the ADCCP Lapb Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_ADCCP " + fi + ADCCP_PROT=YES + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "ASYHDLC" > /dev/null + if [ $? -eq 0 ]; then + if [ $ASYHDLC_PROT != YES ]; then + echo "Enabling the ASYHDLC API Protocol" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_ASYHDLC " + fi + ASYHDLC_PROT=YES + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "AFT_TE1" > /dev/null + if [ $? -eq 0 ]; then + if [ $AFT_TE1_PROT != YES ]; then + echo "Enabling the AFT TE1 Support" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_TE1 -DCONFIG_PRODUCT_WANPIPE_CODEC_SLINEAR_LAW" + fi + AFT_TE1_PROT=YES + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "AFT_TE3" > /dev/null + if [ $? -eq 0 ]; then + if [ $AFT_TE3_PROT != YES ]; then + echo "Enabling the AFT TE3 Support" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_AFT_TE3 " + fi + AFT_TE3_PROT=YES + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "LIPAPI" > /dev/null + if [ $? -eq 0 ]; then + if [ $XDLC_PROT != YES ]; then + echo "Enabling the XDLC Support" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_XDLC " + fi + if [ $LAPB_PROT != YES ]; then + echo "Enabling the LAPB Support" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_LIP_LAPB -DCONFIG_PRODUCT_WANPIPE_LIP_LAPD " + fi + XDLC_PROT=YES + LAPB_PROT=YES + LIPAPI_PROT=YES + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "TDM" > /dev/null + if [ $? -eq 0 ]; then + tdmv_get_zaptel_path + if [ $? -eq 0 ]; then + ZAP_MOD_DIR=/lib/modules/$(uname -r) + + if [ $KERN_VER -eq 24 ]; then + ZAPTEL_NAME=zaptel.o + else + ZAPTEL_NAME=zaptel.ko + fi + + if [ -e $ZAP_MOD_DIR/zaptel/$ZAPTEL_NAME ] && [ -e $ZAP_MOD_DIR/misc/$ZAPTEL_NAME ]; then + echo + echo "-------------------------------------------------------------" + echo "CRITICAL WARNING: Multiple ZAPTEL Installations Found" + echo + echo "./Setup has found MULTIPLE ZAPTEL driver installations in:" + echo " $ZAP_MOD_DIR/zaptel and" + echo " $ZAP_MOD_DIR/misc directory." + echo + echo " The ZAPTEL drivers in $ZAP_MOD_DIR/zaptel are OLD." + echo + echo " This is illegal, and CAN cause Wanpipe to CRASH." + echo + echo " Please solve this PROBLEM by removing OLD ZAPTEL" + echo " kerenl modules before installing WANPIPE. " + echo + echo " eg: rm -rf $ZAP_MOD_DIR/zaptel" + echo " depmod -a" + echo + echo " For more info please Contact Sangoma Technologies." + echo "-------------------------------------------------------------" + + TDM_PROT=NO + TDM_DCHAN= + echo + + exit 1 + else + echo + + if [ $TDM_PROT != YES ]; then + echo "Enabling the TDM Voice Asterisk Support" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE " + ASTERISK_IFLAGS="-I$ZAPTEL_INSTALL_DIR" + WANCFG_ZAPTEL_CFG=YES + fi + + + eval "grep ZT_DCHAN_TX_V2 $ZAPTEL_INSTALL_DIR/* 2> /dev/null > /dev/null" + if [ $? -eq 0 ]; then + TDM_DCHAN="(DCHAN)" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN" + echo "Sangoma DCHAN Patch detected in zaptel" + fi + + + if [ "$TDM_DCHAN" = "" ]; then + echo + echo + getyn "Enable TDMV DCHAN Native HDLC Support & Patch Zaptel (recommended) ?" + if [ $? -eq 0 ]; then + + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN" + echo + eval "$PROD_HOME/patches/sangoma-zaptel-patch.sh $ZAPTEL_INSTALL_DIR" + result=$? + if [ $result -eq 0 ]; then + TDM_DCHAN="(DCHAN)" + echo " Zaptel DCHAN Patch successful" + echo + elif [ $result -eq 1 ]; then + TDM_DCHAN="(DCHAN)" + echo + else + echo "Zaptel Update Failed!" + echo + echo "Your zaptel source is now corrupted" + echo "Please untar new zaptel source in $ZAPTEL_INSTALL_DIR." + echo + echo "Please contact Sangoma support!" + echo + TDM_DCHAN= + + exit 1 + fi + fi + fi + if [ $ZAP_CHUNK_OP == "YES" ] ; then + tdmv_apply_zaptel_chunk_patch + fi + + #################################################################### + if [ $ENABLE_ECHO_DEBUG -eq 1 ]; then + getyn "Compile Echo Debugging Support for Zaptel ? " + if [ $? -eq 0 ]; then + tdmv_apply_zaptel_echo_debug_patch + if [ $? -eq 0 ]; then + zaptel_modified=1 + else + ENABLE_ECHO_DEBUG=0 + echo + echo "Echo Debug Patch Failed!! Your Zaptel source may be corrupted!!" + fi + getyn " Confirm Echo Debugging Support for Zaptel Patching ?" + echo + if [ $? -eq 1 ]; then + exit 1 + fi + fi + fi + #################################################################### + + if [ $ENABLE_EDAC -gt 0 ] && [ "$ECHO_MASTER_PROT" = "NO" ]; then + echo + getyn "Compile TDMV Echo Detection and Control (EDAC) Support (y/n)? " + if [ $? -eq 0 ]; then + echo + tdmv_apply_zaptel_edac_patch + if [ $? -eq 0 ]; then + echo + echo "Note: Please recompile/reinstall ZAPTEL drivers" + echo + echo + getyn "Confirm EDAC Zaptel Patching: yes/no to continue!" + + #now patch Asterisk + tdmv_apply_asterisk_edac_patch + ############################## + if [ $? -eq 0 ]; then + #both Zaptel and Asterisk patched successfully + zaptel_modified=1 + asterisk_modified=1 + getyn "Confirm EDAC Asterisk Patching: yes/no to continue!" + ECHO_MASTER_PROT=YES + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER" + else + echo + ECHO_MASTER_PROT=NO + fi + ############################## + else + echo + ECHO_MASTER_PROT=NO + fi + fi + fi + + TDM_PROT=YES + zaptel_modified=1; + if [ $zaptel_modified ] && [ $zaptel_modified -eq 1 ] && [ "$ZAPTEL_COMPILE_DISABLE" = "NO" ]; then + echo + getyn "Recompile/reinstall Zaptel (recommended) ?" + if [ $? -eq 0 ]; then + tdmv_compile_zaptel + else + echo " Recompile/reinstall zaptel after Wanpipe installation" + fi + fi + if [ $asterisk_modified ] && [ $asterisk_modified -eq 1 ]; then + getyn "Your Asterisk source was modified, recompile/reinstall zaptel ?" + if [ $? -eq 0 ]; then + echo "DavidY: Compile Asterisk here" + # tdmv_compile_asterisk + else + echo " Recompile/reinstall Asterisk after Wanpipe installation" + fi + fi + tdmv_check_zaptel_udev + fi + fi + PROT_MATCH=YES + fi + + echo "$PROTOCOL" | grep "MPAPI" > /dev/null + if [ $? -eq 0 ]; then + + if [ ! -d $DRIVER_UPDATE_DIR/src/net/annexg ]; then + + if [ $ARG = YES ]; then + ANNEXG_LOAD=YES; + else + + cat < /dev/null + if [ $? -eq 0 ]; then + + if [ ! -f $DRIVER_UPDATE_DIR/src/net/sdla_ss7.c ]; then + cat < /dev/null | cut -d ' ' -f3 | cut -d '.' -f1` + if [ ! -z $rpmver ] && [ $rpmver -lt 4 ]; then + RPMOPT="--buildroot" + else + if [ $use_rpmbuild -eq 1 ]; then + RPMOPT="--buildroot" + else + RPMOPT="--root" + fi + fi +} + +function compile_aft_firmware_util() +{ + lhome=`pwd` + \cp -f $PROD_HOME/util/wan_aftup $PROD_HOME/rpmbuild/etc/wanpipe/firmware/ -r + + cd $PROD_HOME/rpmbuild/etc/wanpipe/firmware/wan_aftup + echo "Compiling firmware update utilities..." + eval "make wan_aftup" >/dev/null 2>/dev/null + if [ ! $? -eq 0 ]; then + echo "failed" + exit + else + echo "done" + fi + + + \rm -f *.c + \rm -f *.o + \rm -f *.h + \rm -f Makefile + cd $lhome +} + +function usage() +{ + if [ "$PKG_NAME" != "wanpipe-lite" ]; then + cat < : Help + + optional command extensions: + ---------------------------- + + --silent : Non interactive. Run all above commands + without user interaction. Thus default + environment values are assumed such + as: + + Linux source dir: $SOURCEDIR + Architecture : uname -m + Kernel Image : uname -r + + --builddir : Install WANPIPE package into a virtual + directory. The path must be + absolute and must exist. Default is set + to system root( / ). + eg: --builddir=/root/wanpipe_build + + --with-linux: Build modules using a custom linux + source directory. Default value is + set to $SOURCEDIR + eg: --with-linux=/usr/src/linux-2.4.4 + + --arch : Build modules using a custom defined + architecture. (i686 or i586) + By default: (uname -m) + eg: --arch=i686 + + --split_rpms: Option to split the rpm build into + util and modules package. Thus, + splitting user space utilities and + kernel modules into two packages. + Default: one rpm package containing + both utilites and modules. + eg: ./Setup buildrpm --split_rpms + + --linux-vanilla: Compile wanpipe drivers as if the + current linux source is a vanilla source. + Used to remove the default assumption that + stock distribution kernels pull changes + from higher linux kernel versions. + + --no-gcc-debug: Remove -g option out of gcc compile argumetns. + + + --protocol: Option to compile in extra protocols + that are not installed by default. + eg: ./Setup install --protocol= + + Extra Protocols Supported: + + SS7 : SS7 Level 2 API prot support + + BITSTRM: BitStreaming Protocol support + + BSCSTRM: Nasdaq BiSync API protocol + + BISYNC : Multi-Point Bisync API protocol + + SDLC : SDLC API protocol support + + EDU : Wan EduKit Driver suporrt + + POS : POS (S509/S515) hw/prot support + + SDLC : SDLC API protocol + + MPAPI : Multi Protocol API: X25,LAPB,DSP + + ADCCP : ADCCP API protocol (LapB) + + TDM : Hardware TDM VOICE support to Asterisk PBX + + + +ENDOFTEXT + + else + cat <: Help + +ENDOFTEXT + fi + return 0 +} + +####### MAIN ################################################################# +# set -x + + +PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin +KERNEL_VERSION=`uname -r` +KERNEL_UNAME=`uname -r` +PKG_NAME=wanpipe +DISTR_NAME="WANPIPE" +PROD=wanrouter +PROD_VER=3.2.1.2 +PROD_HOME=`pwd` +META_CONF=$PROD_HOME/$PROD.rc +WAN_INTR_DIR=$PROD_HOME/interfaces +WAN_CONF_DIR=$PROD_HOME +PROD_CONF=$WAN_CONF_DIR/wanpipe1.conf +PROD_PATCH=$PROD_HOME/patches +PROD_INIT=/usr/sbin/ +FILELIST=$PROD_HOME/Filelist +SOURCEDIR=/lib/modules/$(uname -r)/build +START_SCRIPT=S11$PROD +OLD_START=S05router +STOP_SCRIPT=K70$PROD +OLD_STOP=K10router +INCLUDE=$SOURCEDIR/include/linux +ROUTER_RC=$META_CONF +UTIL_DIR=$PROD_HOME/util +UTIL_BIN_DIR=$PROD_HOME/util/bin +FIX_211="Fix_below_2211.gz" +ARCH=`uname -m` +WAN_TOOLS="wanconfig sdladump wanpipemon wanpipemon_legacy wpkbdmon wpbackupd" +WANROUTER_STARTUP_SMPL=$PROD_HOME/samples/wanrouter +WANROUTER_STARTUP=/usr/sbin/wanrouter +LINUX_VANILLA=0 +DISABLE_GCC_DEBUG=0 +ENABLE_EDAC=0 +ENABLE_ECHO_DEBUG=0 +ZAPTEL_PATH_OP="NO" +ZAPTEL_COMPILE_DISABLE="NO" +ZAP_CHUNK_OP="NO" +CMP_LOG=$PROD_HOME/setup_drv_compile.log +CMP_BUILD=build.sh +CMP_INSTALL=install.sh +CMP_CLEAN=clean.sh +DEVEL_DEBUG=NO +SSMG_DIR=ssmg +WANPIPE_INCLUDE_DIR=/usr/include/wanpipe +WANCFG_ZAPTEL_CFG=NO +WANCFG_ZAPTEL=/usr/sbin/wancfg_zaptel +find_zap_dir_quit=0 +zaptel_auto_install="NO" + +ARCH=i386 + + +echo > $CMP_LOG +echo "WANPIPE DRIVER COMPILE LOG" >> $CMP_LOG +echo "`date`" >> $CMP_LOG +echo "-----------------------------------" >> $CMP_LOG + + + +DRIVERS_MOD_LIST="sdladrv.mod.c wanrouter.mod.c wanpipe_syncppp.mod.c wanpipe.mod.c af_wanpipe.mod.c" +DRIVERS_MPAPI_MOD_FILES="wanpipe_lapb.mod.c wanpipe_x25.mod.c wanpipe_dsp.mod.c" + +DRIVERS_MPAPI_DSP="dsp_timer.c dsp_subr.c dsp_proc.c dsp_out.c dsp_in.c dsp_iface.c dsp_api_iface.c" +DRIVERS_MPAPI_LAPB="lapb_iface.c lapb_in.c lapb_out.c lapb_proc.c lapb_subr.c lapb_timer.c lapb_x25_iface.c" +DRIVERS_MPAPI_X25="x25_api_iface.c x25_dsp_iface.c x25_facils.c x25_iface.c x25_in.c x25_out.c x25_proc.c x25_subr.c x25_switch.c x25_timer.c x25_utils.c" + + +DRIVER_UPDATE_DIR=$PROD_PATCH/kdrivers +DRIVER_TMP_DIR=$PROD_HOME/kdrvtmp +DRIVERS_COMPILED=no +NEW_IF_TYPE=NO + +MAKE_PATCH_22X="makefile.patch.2.2.X" +MAKE_PATCH_240="makefile.patch.2.4.0" +MAKE_PATCH_244="makefile.patch.2.4.4" +MAKE_UTILS_PATCH_24X="makefile.patch.utils.2.4.X" +MAKE_UTILS_PATCH_22X="makefile.patch.utils.2.2.X" +AF_WANPIPE_MAKE_PATCH_24X="makefile.af_wanpipe.patch" + +TEMP=$PROD_HOME/temp.$$ +WANCFG=$PROD_HOME/util/wancfg_legacy/wancfg_legacy +CFGFT1=$PROD_HOME/util/ft1/wanpipe_cfgft1 + + +RPMOPT="--root" +PROTOCOL="" +EXTRA_LINK_MODULES="" +PROTOCOL_DEFINES="-DCONFIG_PRODUCT_WANPIPE_BASE " +SS7_USER_ID="0" + +ANNEXG_LOAD=NO +SCTP_LOAD=NO + +ZAPTEL_DFLT_INSTALL_DIR="/usr/src/zaptel" +ZAPTEL_INSTALL_DIR=$ZAPTEL_DFLT_INSTALL_DIR +ZAPTEL_C_FILE="zaptel.c" +ASTERISK_IFLAGS= +EDAC_ZAP_PATCH_FILE=ed_zaptel.patch + +ASTERISK_INSTALL_DIR="/usr/src/asterisk" +EDAC_ASTERISK_PATCH_FILE=ed_asterisk.patch +EDAC_ASTERISK_CVS_PATCH_FILE=ed_asterisk_cvs.patch + +######################################################################## +# D channel "search and replace" version of patch +ZAPTEL_C_SEARCH_STR="chan->writen\[chan->inwritebuf\] = amnt;" +ZAPTEL_C_PATCH="if ((chan->flags \& ZT_FLAG_HDLC) \&\& chan->span->ioctl != NULL){\n\ + if (chan->span->ioctl(chan, ZT_DCHAN_TX_V2, amnt)==0){\n\ + return amnt;\n\ + }\n\ + }\n\ + chan->writen[chan->inwritebuf] = amnt;" +# D channel patching for zaptel version 1.2.17.1/1.4.2.1 or above +ZAPTEL_C_SEARCH_STR_NEW="chan->writen\[res\] = amnt;" +ZAPTEL_C_PATCH_NEW="if ((chan->flags \& ZT_FLAG_HDLC) \&\& chan->span->ioctl != NULL){\n\ + if (chan->span->ioctl(chan, ZT_DCHAN_TX_V2, amnt)==0){\n\ + return amnt;\n\ + }\n\ + }\n\ + chan->writen[res] = amnt;" +# Zaptel 1.4.2.1 "Menuselect" issue +ZAPTEL_MENUSELECT_SEARCH_STR="autoconf" +ZAPTEL_MENUSELECT_REMOVE=" " + +#NOTE1: the 'sed' command does NOT work on more than one line, so the +#closing '*/' will be pushed AFTER the inserted strings. +ZAPTEL_H_SEARCH_STR=" \* 80-85 are reserved for dynamic span stuff" +ZAPTEL_H_PATCH=\ +" \* 80-85 are reserved for dynamic span stuff\n\ + \*\/\n\ +#define ZT_DCHAN_TX _IOR (ZT_CODE, 60, int)\n\ +#define ZT_DCHAN_TX_V1 ZT_DCHAN_TX\n\ +#define ZT_DCHAN_TX_V2 ZT_DCHAN_TX\n\/\*" +#NOTE2: the "/*" at the end needed to match the leftover '*/' after the comment +######################################################################## +#Echo Debug patch is done in 2 parts: 1. is search and replace +# 2. using 'patch' program +#The reason is: 'patch' alone fails, if DCHAN patch already applied +ZAPTEL_C_ECHO_DEBUG_PATCH=zaptel.c.echo_debug.patch +ZAPTEL_H_ECHO_DEBUG_PATCH=zaptel.h.echo_debug.patch + +ZAPTEL_H_ECHO_DEBUG_PATCH_STR=\ +" \* 80-85 are reserved for dynamic span stuff\n\ + \*\/\n\ +#define GET_ECHO_SPIKE_SAMPLE _IOR (ZT_CODE, 64, int)\n\ +#define SEND_ECHO_SPIKE _IOR (ZT_CODE, 65, int)\n\/\*" + +######################################################################## +setup_cmd=$1; + +# Detect distribution type (FULL or LITE) +DIR=${PROD_HOME##/*/} +if [ $DIR = "wanpipe_lite" ]; then + PKG_NAME=wanpipe-lite + DISTR_NAME="WANPIPE (LITE)" + PROD_VER=`grep "WANPIPE_LITE_VERSION *\"" "${DRIVER_UPDATE_DIR}/include/wanpipe_version.h" | cut -d'"' -f2` + PROD_VER=`echo $PROD_VER | awk '{ gsub(" ", "") ; print }'` + if [ -z $PROD_VER ]; then + PROD_VER=1.1.1 + fi + if [ "$setup_cmd" != "install" -a "$setup_cmd" != "remove" ]; then + usage + exit 1 + fi +fi + +#Initialize supportd protocols +#that are not compiled by default +init_all_protocols + +#List of available non-standard protocols +#Used as part of an errror message +AVAIL_PROTOCOLS=" + SS7 EDU BISYNC BITSTRM BSCSTRM SDLC + POS EDU SDLC MPAPI ADCCP TDM +" + +#Enable default protocols +DEFAULT_PROTOCOLS="FR-CHDLC-PPP-MFR-MPROT-X25-AFT_TE1-AFT_TE3" +API_PROTOCOLS="SS7-BISYNC-BSCSTRM-BITSTRM-POS-EDU-SDLC-MPAPI-ADCCP-TDM-XDLC-ASYHDLC" + +CC=gcc +USR_CC= +KBUILD_VERBOSE=0 +KBUILD_DISABLE=0 +NO_AUTO_START=0 +PROTS= + +ROOT=; + +WITH_LINUX_OP="NO"; +SPLIT_RPMS="NO"; + +check_bash +check_awk + +#Check for kernel series 2.2.X or 2.4.X +eval "uname -r | grep \"^2.4.*\" > /dev/null" +if [ $? -eq 0 ]; then + KERN_VER=24 + LINUXDRIVERS_NET="drivers/net/wan" + DEFAULT_PROTOCOLS=$DEFAULT_PROTOCOLS"-ADSL-ATM" +else + + eval "uname -r | grep \"^2.6.*\" > /dev/null" + if [ $? -eq 0 ]; then + KERN_VER=26 + LINUXDRIVERS_NET="drivers/net/wan" + DEFAULT_PROTOCOLS=$DEFAULT_PROTOCOLS"-ADSL-ATM" + else + KERN_VER=22 + LINUXDRIVERS_NET="drivers/net" + + eval "uname -r | grep \"^2.0.*\" > /dev/null" + if [ $? -eq 0 ]; then + echo + echo "Wanpipe drivers do not support 2.0.X kernels !!!" + echo "Please upgrade to 2.2.X 2.4.X 2.6.X kernels" + echo "or install an older version of wanpipe, version 2.2.2" + echo + exit 0; + fi + fi +fi +LINUXDRIVERS_WAN="net/wanrouter" + +superuser=NO; +if [ "$UID" = 0 ]; then + superuser=YES; +fi + +# Check router home directory. +[ -d "$PROD_HOME" ] || { + error "Router home directory ($PROD_HOME) not found" + exit 1 +} + +NONINTERACTIVE=; + +if [ "$setup_cmd" = "remove_init" ]; then + remove_init; + find /etc/rc* | grep wan + exit; +fi + +if [ "$setup_cmd" = "install_init" ]; then + install_init; + find /etc/rc* | grep wan + exit; +fi + +if [ "$setup_cmd" = "uninstall" ] || [ "$setup_cmd" = "remove" ]; then + remove; + uninstall_all + exit; +fi + +if [ "$setup_cmd" = "zaptel" ]; then + setup_cmd="install" + zaptel_auto_install="YES" + #EXTRA_ARGS=" --protocol=TDM --silent --no-zaptel-compile " + EXTRA_ARGS=" --protocol=TDM --silent " +fi + +if [ "$setup_cmd" = "buildrpm" ]; then + EXTRA_ARGS=" --no-zaptel-compile " +fi + +if [ "$PKG_NAME" != "wanpipe-lite" ]; then + + ARGS=$EXTRA_ARGS + while [ ! -z "$2" ]; + do + ARGS_tmp=$ARGS"$2 " + ARGS=$ARGS_tmp + shift + done + + #echo "ARGS: $ARGS" + + for arg in $ARGS + do + #echo + #echo "ARG VAL=$arg" + + case $arg in + + --silent*) + NONINTERACTIVE=1; + ;; + --linux-vanilla*) + LINUX_VANILLA=1; + ;; + --no-gcc-debug*) + DISABLE_GCC_DEBUG=1; + ;; + + --usr-cc*) + USR_CC=`echo $arg | cut -d'=' -f2`; + eval "type $USR_CC"; + if [ $? -ne 0 ]; then + echo "Error C compiler: $USR_CC doesnt exist!" + exit 1 + fi + + check_gcc + if [ $? -ne 0 ]; then + echo "Error: Failed to determine $USR_CC version"; + exit 1 + fi + CC=$USR_CC + ;; + --kbuild-verbose*) + KBUILD_VERBOSE=1 + ;; + --devel-debug*) + DEVEL_DEBUG="YES" + ;; + --kbuild-disable*) + KBUILD_DISABLE=1 + ;; + --edac*) + #TAKEN OUT + ;; + --noautostart*) + NO_AUTO_START=1 + ;; + + --ignore-t1-yellow*) + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DWANPIPE_IGNORE_T1_YELLOW " + ;; + + --64bit_4G*) + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DWANPIPE_64BIT_4G_DMA " + ;; + + --hwec_noise_reduction*) + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DWANEC_ENABLE_NOISE_REDUCTION " + ;; + + --with-linux*) + SOURCEDIR=`echo $arg | cut -d'=' -f2`; + if [ "$SOURCEDIR" = "" ]; then + echo "Error invalied --with-linux option"; + exit 1; + fi + if [ ! -d "$SOURCEDIR" ]; then + echo "Error: Linux source directory not found: $SOURCEDIR"; + exit 1; + fi + if [ ! -f "$SOURCEDIR/Makefile" ]; then + echo "Error: No vaild linux source found in $SOURCEDIR"; + exit 1; + fi + INCLUDE=$SOURCEDIR/include/linux + WITH_LINUX_OP="YES"; + ;; + + --echo-debug*) + ENABLE_ECHO_DEBUG=1; + ;; + + --zaptel-path*) + ZAPTEL_INSTALL_DIR=`echo $arg | cut -d'=' -f2`; + if [ "$ZAPTEL_INSTALL_DIR" = "" ]; then + echo "Error invalid --zaptel-path option"; + exit 1; + fi + if [ ! -d "$ZAPTEL_INSTALL_DIR" ]; then + echo "Error: Zaptel source directory not found: $ZAPTEL_INSTALL_DIR"; + exit 1; + fi + if [ ! -f "$ZAPTEL_INSTALL_DIR/Makefile" ]; then + echo "Error: Invalid zaptel source found in $ZAPTEL_INSTALL_DIR"; + exit 1; + fi + ZAPTEL_PATH_OP="YES"; + echo "Zaptel path defined as: $ZAPTEL_INSTALL_DIR" + ;; + + --with-zaptel*) + ZAPTEL_INSTALL_DIR=`echo $arg | cut -d'=' -f2`; + if [ "$ZAPTEL_INSTALL_DIR" = "" ]; then + echo "Error invalid --with-zaptel option"; + exit 1; + fi + if [ ! -d "$ZAPTEL_INSTALL_DIR" ]; then + echo "Error: Zaptel source directory not found: $ZAPTEL_INSTALL_DIR"; + exit 1; + fi + if [ ! -f "$ZAPTEL_INSTALL_DIR/Makefile" ]; then + echo "Error: Invalid zaptel source found in $ZAPTEL_INSTALL_DIR"; + exit 1; + fi + ZAPTEL_PATH_OP="YES"; + echo "Zaptel path defined as: $ZAPTEL_INSTALL_DIR" + ;; + + --no-zaptel-compile*) + ZAPTEL_COMPILE_DISABLE="YES"; + ;; + + --builddir*) + ROOT=`echo $arg | cut -d'=' -f2`; + if [ "$ROOT" = "" ]; then + echo "Error: invalid --builddir option"; + exit 1; + fi + tmp_val=`echo $ROOT | cut -d'/' -f1` + if [ "$tmp_val" != "" ]; then + echo "Error: invalid builddir directory: must be absolute path!"; + exit 1; + fi + if [ ! -d "$ROOT" ]; then + echo "Error: builddir ($ROOT) not found: please create it first!"; + exit 1; + fi + export ASTBROOT=$ROOT; + ASTBROOT=$ROOT; + + TMP_123=${WANPIPE_INCLUDE_DIR#/*} + WANPIPE_INCLUDE_DIR=$ROOT/$TMP_123 + TMP_123=${WANCFG_ZAPTEL#/*} + WANCFG_ZAPTEL=$ROOT/$TMP_123 + + ;; + --acflags*) + USER_CFLAGS=`echo $arg | cut -d'=' -f2` + if [ "$USER_CFLAGS" = "" ]; then + echo "Error: invalid --acflags option: [ string ]"; + fi + ;; + + --ocflags*) + USE_CFLAGS=`echo $arg | cut -d'=' -f2` + if [ "$USER_CFLAGS" = "" ]; then + echo "Error: invalid --ocflags option: [ string ]"; + fi + ;; + + --protocol*) + PROTS=`echo $arg | cut -d'=' -f2`; + ;; + + --ss7_user_id*) + SS7_USER_ID=`echo $arg | cut -d'=' -f2`; + if [ "$SS7_USER_ID" = "" ]; then + echo "Error: invalid --ss7_user_id option: [ integer ]"; + fi + ;; + + --ss7_ioctl_api*) + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DSS7_IOCTL_INTERFACE " + ;; + + --arch*) + ARCH=`echo $arg | cut -d'=' -f2`; + + if [ $ARCH != "i686" ] && [ $ARCH != "i586" ] && [ $ARCH != "i486" ] && [ $ARCH != "i386" ] && [$ARCH !="x86_64" ]; then + echo "Error: Invalid Architecture [i686|i586|i486|i386|x86_64]\n" + exit 1; + fi + ;; + --split_rpms*) + SPLIT_RPMS="YES"; + ;; + --force_smp) + FORCE_SMP="YES"; + ;; + --gz-modules) + GZ_MODULES="YES"; + ;; + --zap-chunk*) + ZAP_CHUNK=`echo $arg | cut -d'=' -f2`; + + if [ $ZAP_CHUNK != "8" ] && [ $ZAP_CHUNK != "16" ] && [ $ZAP_CHUNK != "40" ] && [ $ZAP_CHUNK != "80" ]; then + echo "Error: Invalid Zaptel Chunk size" + exit 1; + else + echo "WARNING: Zaptel custom chunk option is EXPERIMENTAL" + echo "The wct4xxp module will be removed from your system" + getyn "Do you want to use custom Zaptel chunk size of $ZAP_CHUNK" + if [ $? -eq 0 ]; then + ZAP_CHUNK_OP="YES" + else + ZAP_CHUNK_OP="NO" + fi + fi + ;; + *) + echo "Invalid option $arg" + exit 1; + ;; + esac + done + + if [ "$zaptel_auto_install" = "YES" ] && [ "$ZAPTEL_PATH_OP" != "YES" ]; then + find_zap_dirs + fi + + if [ "$PROTS" != "" ]; then + echo "$PROTS" | grep "DEF" > /dev/null + if [ $? -eq 0 ]; then + enable_protocols $DEFAULT_PROTOCOLS "YES" + fi + + echo "$PROTS" | grep "^API" > /dev/null + if [ $? -eq 0 ]; then + enable_protocols $API_PROTOCOLS "YES" + fi + + echo "$PROTS" | grep "ALL" > /dev/null + if [ $? -eq 0 ]; then + enable_protocols $DEFAULT_PROTOCOLS "YES" + enable_protocols $API_PROTOCOLS "YES" + fi + + echo "$PROTS" | grep "TDM" > /dev/null + if [ $? -eq 0 ]; then + enable_protocols AFT_TE1 "YES" + fi + + enable_protocols "$PROTS" "YES" + if [ $? -ne 0 ]; then + exit 1 + fi + fi + + + if [ "$setup_cmd" = "drivers" ]; then + apply_patches || exit 1 + compile_drivers || exit 1 + exit; + fi + + if [ "$setup_cmd" = "utility" ]; then + compile_src; + exit; + fi + + if [ "$setup_cmd" = "meta" ]; then + install_config; + exit; + fi + + if [ "$setup_cmd" = "inst" ]; then + install_all; + exit; + fi + + if [ "$setup_cmd" = "ssmg" ]; then + SSMG=YES + install_ssmg; + exit; + fi + + if [ "$setup_cmd" = "buildrpm" ] || [ "$setup_cmd" = "builddeb" ]; then + + if [ ! -d $SOURCEDIR ]; then + echo + echo "Error: Linux source dir $SOURCEDIR not found!" + echo + exit + fi + + if [ "$setup_cmd" = "buildrpm" ]; then + build_dir=rpmbuild + package_name="RPM" + else + build_dir=debbuild + package_name="DEB" + fi + + + if [ -d $PROD_HOME/$build_dir ]; then + \rm -rf $PROD_HOME/$build_dir > /dev/null 2> /dev/null + fi + + \mkdir -p $PROD_HOME/$build_dir + + PROTS=${PROTS:-$DEFAULT_PROTOCOLS} + + enable_protocols $PROTS + + get_kernel_ver $SOURCEDIR + + banner + + echo " + + WANPIPE $package_name BUILD + +Wanpipe $package_name will be build based on the +following Environment variables. + + 1. Linux Source Dir : $SOURCEDIR + + 2. Linux Source Name : $KERNEL_VERSION + + 3. Current Image Name: $KERNEL_UNAME + + 4. CPU Type : $ARCH + + 5. Wan Protocols : $PROTS + + 6. Build Directory : $PROD_HOME/$build_dir +" + + if [ $TDM_PROT = "YES" ]; then +echo " 7. Zaptel Build Dir : $ZAPTEL_INSTALL_DIR " + fi + echo + echo + if [ $KERNEL_UNAME != $KERNEL_VERSION ]; then + + echo " +WARNING: + +The items 2 and 3 should usually be identical! + +If they are not, you are building an $package_name for +a different kernel image name, Setup is assuming +you know what you are doing :) + +" + fi + + getyn "Would you like to build WANPIPE $package_name ?" + if [ $? -ne 0 ]; then + exit 1 + fi + + + $PROD_HOME/Setup install --silent --builddir=$PROD_HOME/$build_dir --with-linux=$SOURCEDIR --arch=$ARCH --protocol=$PROTS --ss7_user_id=$SS7_USER_ID --noautostart --no-zaptel-compile --zaptel-path=$ZAPTEL_INSTALL_DIR + + if [ $? -ne 0 ]; then + echo "Error: WANPIPE Installation Failed!" + exit 1; + fi + + + if [ "$setup_cmd" = "buildrpm" ]; then + compile_aft_firmware_util + detect_rpm_build_utility + + + if [ "$SPLIT_RPMS" = "YES" ]; then + eval "$RPM -bb --define '_unpackaged_files_terminate_build 0' $RPMOPT $PROD_HOME/rpmbuild $PROD_HOME/rpmspec/wanpipe-util.spec --target=$ARCH" + eval "$RPM -bb --define '_unpackaged_files_terminate_build 0' --define 'kern_ver $KERNEL_VERSION' $RPMOPT $PROD_HOME/rpmbuild $PROD_HOME/rpmspec/wanpipe-mod.spec --target=$ARCH" + else + eval "$RPM -bb --define 'kern_ver $KERNEL_VERSION' $RPMOPT $PROD_HOME/rpmbuild $PROD_HOME/rpmspec/wanpipe.spec --target=$ARCH" + fi + if [ $? -eq 0 ]; then + cat < + + +ENDOFTEXT + + else + cat < /dev/null 2> /dev/null + + if [ $? -eq 0 ]; then + + pver=${PROD_VER//\./} + build_pkg_name="wanpipe_"$pver"-k"$KVER$KPATCH$KLVL$KEVER"_"$ARCH".deb" + + mv -f "$build_dir.deb" $build_pkg_name + + cat < + + +ENDOFTEXT + else + cat < /dev/null 2> /dev/null + fi + exit 0; + + + fi + + if [ "$1" = "helprpm" ]; then + + detect_rpm_build_utility + + cat < --arch= + + Create a custom rpm using the kernel in + --with-linux directory. Default kernel + location is $SOURCEDIR. + + 1. The absolute path must point to a + configured (.config file must exist) + kernel source. If path is not supplied + it's defaulted to $SOURCEDIR. + + 2. The RPM will be build in a virtual + directory called $PROD_HOME/rpmbuild/. Thus, it + will not pollute current environment + except the patches added to the + linux source directory (defined above). + + 3. --arch is used to specify architecutre option + during compilation of wanpipe kernel modules. + Supported options: i686 to i386. + By default architecture is obtained using the 'uname -m' + command. + +In order to further customise a WANPIPE +RPM the user can manully create one. + +1) Install WANPIPE package into a virtual + directory (eg: $PROD_HOME/rpmbuild) + + ./Setup install --silent --builddir=$PROD_HOME/rpmbuild + +2) Customize the $PROD_HOME/rpmbulid directory. + + eg: Copy already created wanpipe1.conf + configuration file into + $PROD_HOME/rpmbuild/etc/wanpipe directory. + + So that the RPM installation will + already have a configured wanpipe card. + +3) Build the rpm based on the $PROD_HOME/rpmbuild + directory: + + $RPM -bb $RPMOPT $PROD_HOME/rpmbuild \\ + $PROD_HOME/rpmspec/wanpipe.spec + +ENDOFTEXT + exit 0; + fi +fi + + +if [ "$setup_cmd" != "install" ] && [ "$setup_cmd" != "upgrade" ]; then + usage + exit 1 +fi + +welcome || exit 0 +prepare || exit 1 +apply_patches || exit 1 +compile_drivers || exit 1 +install_init || exit 1 +install_config || exit 1 +compile_src || exit 1 +install_all +install_ssmg +clean_up +goodbye + + +if [ -z $NONINTERACTIVE ] && [ "$WANCFG_ZAPTEL_CFG" = "YES" ] && [ -e $WANCFG_ZAPTEL ]; then + echo + echo "Wanpipe / Zaptel Configuration" + echo "==============================" + echo + echo "wancfg_zaptel configurator can create all wanpipe devices" + echo "for ZAPTEL as well as /etc/zaptel.conf file." + echo "Optionally: wancfg_zaptel can also create Asterisk zapata.conf" + echo "-----------------------------------------------------" + getyn "Would you like to configure wanpipe devices for ZAPTEL?" + if [ $? -eq 0 ]; then + eval "$WANCFG_ZAPTEL" + else + echo "Wanpipe Installation Complete" + echo "-----------------------------" + echo "Please proceed to configure wanpipe user /usr/sbin/wancfg" + echo + fi +fi + diff --git a/tmp/diff b/tmp/diff new file mode 100644 index 0000000..4577b64 --- /dev/null +++ b/tmp/diff @@ -0,0 +1,101 @@ +--- ../Makefile 2007-10-16 19:21:14.000000000 -0400 ++++ Makefile 2007-10-16 21:35:41.000000000 -0400 +@@ -48,6 +48,7 @@ + WAN_DIR=$(PWD)/$(KMODDIR)/src/net + WANEC_DIR=$(PWD)/$(KMODDIR)/wanec + MODTYPE=ko ++WANPIPE_ETC=/etc/wanpipe + + #Setup include path and extra cflags + EXTRA_CFLAGS := -I$(PWD)/$(WINCLUDE) -I$(PWD)/$(WINCLUDE)/annexg -I$(PWD)/patches/kdrivers/wanec -D__LINUX__ +@@ -96,8 +97,8 @@ + fi + @mkdir -p $(PWD)/ast_build_dir + ./Setup drivers --builddir=$(PWD)/ast_build_dir --with-linux=$(KDIR) $(ZAP_OPTS) --usr-cc=$(CC) --protocol=DEF-$(ZAP_PROT) --no-zaptel-compile --noautostart --silent +- cp -f $(PWD)/ast_build_dir/$(KMOD)/kernel/drivers/net/wan/* $(WAN_DIR)/ +- cp -f $(PWD)/ast_build_dir/$(KMOD)/kernel/net/wanrouter/* $(WAN_DIR)/ ++ cp -f $(PWD)/ast_build_dir/lib/modules/$(KVER)/kernel/drivers/net/wan/* $(WAN_DIR)/ ++ cp -f $(PWD)/ast_build_dir/lib/modules/$(KVER)/kernel/net/wanrouter/* $(WAN_DIR)/ + + + #Clean utilites and kernel modules +@@ -166,6 +167,9 @@ + + #Install kernel modules only + install_kmod: ++ @echo ++ @echo "Wanpipe kmod"; ++ @echo + install -m 644 -D $(WAN_DIR)/wanrouter.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanrouter.${MODTYPE} + install -m 644 -D $(WAN_DIR)/af_wanpipe.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/af_wanpipe.${MODTYPE} + install -m 644 -D $(WAN_DIR)/wanec.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanec.${MODTYPE} +@@ -197,35 +201,44 @@ + + #Install utilities only + install_util: ++ @echo ++ @echo "Install util"; ++ @echo + $(MAKE) -C util install SYSINC=$(PWD)/$(WINCLUDE) CC=$(CC) PREFIX=$(INSTALLPREFIX) + + #Install etc files + install_etc: +- @if [ ! -e $(INSTALLPREFIX)/etc/wanpipe ]; then \ +- mkdir -p $(INSTALLPREFIX)/etc/wanpipe; \ ++ @echo ++ @echo "Wanpipe etc installing in $(INSTALLPREFIX)/$(WANPIPE_ETC)"; ++ @echo ++ @if [ ! -e $(INSTALLPREFIX)/$(WANPIPE_ETC) ]; then \ ++ mkdir -p $(INSTALLPREFIX)/$(WANPIPE_ETC); \ + fi +- @if [ ! -e $(INSTALLPREFIX)/etc/wanpipe/wanrouter.rc ]; then \ +- install -D -m 644 samples/wanrouter.rc $(INSTALLPREFIX)/etc/wanpipe/wanrouter.rc; \ ++ @if [ ! -e $(INSTALLPREFIX)/$(WANPIPE_ETC)/wanrouter.rc ]; then \ ++ install -D -m 644 samples/wanrouter.rc $(INSTALLPREFIX)/$(WANPIPE_ETC)/wanrouter.rc; \ + fi +- @if [ ! -e $(INSTALLPREFIX)/etc/wanpipe/lib ]; then \ +- mkdir -p $(INSTALLPREFIX)/etc/wanpipe/lib; \ ++ @if [ ! -e $(INSTALLPREFIX)/$(WANPIPE_ETC)/lib ]; then \ ++ mkdir -p $(INSTALLPREFIX)/$(WANPIPE_ETC)/lib; \ + fi +- @\cp -f util/wancfg_legacy/lib/* $(INSTALLPREFIX)/etc/wanpipe/lib/ +- @\cp -rf firmware $(INSTALLPREFIX)/etc/wanpipe/ +- @if [ ! -f $(INSTALLPREFIX)/etc/wanpipe/interfaces ]; then \ +- mkdir -p $(INSTALLPREFIX)/etc/wanpipe/interfaces; \ ++ @\cp -f util/wancfg_legacy/lib/* $(INSTALLPREFIX)/$(WANPIPE_ETC)/lib/ ++ @\cp -rf firmware $(INSTALLPREFIX)/$(WANPIPE_ETC)/ ++ @if [ ! -f $(INSTALLPREFIX)/$(WANPIPE_ETC)/interfaces ]; then \ ++ mkdir -p $(INSTALLPREFIX)/$(WANPIPE_ETC)/interfaces; \ + fi +- @\cp -rf samples $(INSTALLPREFIX)/etc/wanpipe +- @if [ ! -d $(INSTALLPREFIX)/etc/wanpipe/scripts ]; then \ +- mkdir -p $(INSTALLPREFIX)/etc/wanpipe/scripts; \ ++ @\cp -rf samples $(INSTALLPREFIX)/$(WANPIPE_ETC) ++ @if [ ! -d $(INSTALLPREFIX)/$(WANPIPE_ETC)/scripts ]; then \ ++ mkdir -p $(INSTALLPREFIX)/$(WANPIPE_ETC)/scripts; \ + fi +- @\cp -rf wan_ec $(INSTALLPREFIX)/etc/wanpipe/ ++ @\cp -rf wan_ec $(INSTALLPREFIX)/$(WANPIPE_ETC)/ + @install -D -m 755 samples/wanrouter $(INSTALLPREFIX)/usr/sbin/wanrouter + @echo +- @echo "Wanpipe etc installed in $(INSTALLPREFIX)/etc/wanpipe"; ++ @echo "Wanpipe etc installed in $(INSTALLPREFIX)/$(WANPIPE_ETC)"; + @echo + + install_inc: ++ @echo ++ @echo "Install inc"; ++ @echo + @if [ -e $(INSTALLPREFIX)/usr/include/wanpipe ]; then \ + \rm -rf $(INSTALLPREFIX)/usr/include/wanpipe; \ + fi +@@ -233,3 +246,9 @@ + @\cp -f $(PWD)/patches/kdrivers/include/*.h $(INSTALLPREFIX)/usr/include/wanpipe/ + @\cp -rf $(PWD)/patches/kdrivers/wanec/oct6100_api/include/ $(INSTALLPREFIX)/usr/include/wanpipe/oct6100_api + @\cp -rf $(PWD)/patches/kdrivers/wanec/*.h $(INSTALLPREFIX)/usr/include/wanpipe/ ++ @echo ++ @echo "End of inc"; ++ @echo ++ ++ ++ diff --git a/tmp/kbuild/Makefile b/tmp/kbuild/Makefile new file mode 100644 index 0000000..78658c4 --- /dev/null +++ b/tmp/kbuild/Makefile @@ -0,0 +1,53 @@ +# Makefile for hello world kernel 2.6 module. -*-makefile-*- +# +# Copyright (C) 2004 Joachim Nilsson +# +# Licensed under the GNU General Public License, v2.0 or later, +# at your option. See the file COPYING for details, or the web +# page http://www.gnu.org/copyleft/gpl.html +# + +OBJS = +MODULE_NAME = +EXTRA_CFLAGS = +KDIR = +$(MODULE_NAME)-objs = $(OBJS) +SUBDIRS=$(PWD) + +RM = @rm -rf +JUNK = *~ *.bak DEADJOE + + +# First pass, kernel Makefile reads module objects +ifneq ($(KERNELRELEASE),) +obj-m := $(MODULE_NAME).o + + +# Second pass, the actual build. +else +KVER ?= $(shell uname -r) +PWD := $(shell pwd) +KBUILD_VERBOSE= + +all: + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules + +clean: + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) clean + +distclean: clean + $(RM) $(JUNK) $(OBJS) + +help: + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) help + + +# Indents the kernel source the way linux/Documentation/CodingStyle.txt +# wants it to be. +indent: + indent -kr -i8 $($(MODULE_NAME)-objs:.o=.c) + +install: + $(MAKE) -C $(KDIR) M=$(SUBDIRS) modules_install + +endif diff --git a/tmp/kbuild/Makefile.wanec b/tmp/kbuild/Makefile.wanec new file mode 100644 index 0000000..b88a52f --- /dev/null +++ b/tmp/kbuild/Makefile.wanec @@ -0,0 +1,57 @@ +# Makefile for hello world kernel 2.6 module. -*-makefile-*- +# +# Copyright (C) 2004 Joachim Nilsson +# +# Licensed under the GNU General Public License, v2.0 or later, +# at your option. See the file COPYING for details, or the web +# page http://www.gnu.org/copyleft/gpl.html +# + +OBJS = +MODULE_NAME = +EXTRA_CFLAGS = +KDIR = +$(MODULE_NAME)-objs = $(OBJS) + +RM = @rm -rf +JUNK = *~ *.bak DEADJOE + +PWD := $(shell pwd) +SUBDIRS=$(PWD) + +# First pass, kernel Makefile reads module objects +ifneq ($(KERNELRELEASE),) +obj-m := $(MODULE_NAME).o + + +# Second pass, the actual build. +else +KVER ?= $(shell uname -r) +PWD := $(shell pwd) +KBUILD_VERBOSE= + +all: + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules + +clean: + $(shell find $(SUBDIRS) -name '*.*o' | xargs rm) + $(shell find $(SUBDIRS) -name '.*.o.cmd' | xargs rm) + $(shell rm -f build.sh) + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) clean + +distclean: clean + $(RM) $(JUNK) $(OBJS) + +help: + $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) help + + +# Indents the kernel source the way linux/Documentation/CodingStyle.txt +# wants it to be. +indent: + indent -kr -i8 $($(MODULE_NAME)-objs:.o=.c) + +install: + $(MAKE) -C $(KDIR) M=$(SUBDIRS) modules_install + +endif diff --git a/tmp/setup.tgz b/tmp/setup.tgz new file mode 100644 index 0000000..f46b68b Binary files /dev/null and b/tmp/setup.tgz differ diff --git a/util/Makefile b/util/Makefile index dc6ff4c..65baa7d 100644 --- a/util/Makefile +++ b/util/Makefile @@ -8,6 +8,7 @@ all: make -C ft1 all CC=$(CC) SYSINC=$(SYSINC) EXTRA_FLAGS="$(EXTRA_FLAGS)" ARCH=$(ARCH) make -C lxdialog all CC=$(CC) SYSINC=$(SYSINC) EXTRA_FLAGS="$(EXTRA_FLAGS)" ARCH=$(ARCH) make -C sdladump all CC=$(CC) SYSINC=$(SYSINC) EXTRA_FLAGS="$(EXTRA_FLAGS)" ARCH=$(ARCH) + make -C lib/hdlc all CC=$(CC) SYSINC=$(SYSINC) EXTRA_FLAGS="$(EXTRA_FLAGS)" ARCH=$(ARCH) make -C wanconfig all CC=$(CC) SYSINC=$(SYSINC) EXTRA_FLAGS="$(EXTRA_FLAGS)" ARCH=$(ARCH) make -C wanec_client all CC=$(CC) SYSINC=$(SYSINC) WANINCDIR=$(WANINCDIR) EXTRA_FLAGS="$(EXTRA_FLAGS)" ARCH=$(ARCH) make -C wan_plxctrl all CC=$(CC) SYSINC=$(SYSINC) EXTRA_FLAGS="$(EXTRA_FLAGS)" ARCH=$(ARCH) @@ -58,3 +59,5 @@ clean: make -C wancfg clean WAN_VIRTUAL=$(WAN_VIRTUAL) make -C wan_aftup clean WAN_VIRTUAL=$(WAN_VIRTUAL) make -C bwm clean WAN_VIRTUAL=$(WAN_VIRTUAL) + make -C lib/hdlc clean WAN_VIRTUAL=$(WAN_VIRTUAL) + diff --git a/util/diff b/util/diff new file mode 100644 index 0000000..4f08d5b --- /dev/null +++ b/util/diff @@ -0,0 +1,343 @@ +diff -dur wancfg_zaptel/A50x.pm wancfg_zaptel_new/A50x.pm +--- wancfg_zaptel/A50x.pm 2007-12-18 17:59:10.000000000 -0500 ++++ wancfg_zaptel_new/A50x.pm 2008-01-02 11:18:51.000000000 -0500 +@@ -13,6 +13,7 @@ + _card => undef, + _fe_line => undef, + _fe_media => 'BRI', ++ _bri_clock_master => 'NO', + _bri_switchtype => 'etsi', + _bri_country => 'europe' + }; +@@ -38,12 +39,19 @@ + return $self->{_fe_media}; + } + ++sub bri_clock_master { ++ my ( $self, $bri_clock_master ) = @_; ++ $self->{_bri_clock_master} = $bri_clock_master if defined($bri_clock_master); ++ return $self->{_bri_clock_master}; ++} ++ + sub bri_switchtype { + my ( $self, $bri_switchtype ) = @_; + $self->{_bri_switchtype} = $bri_switchtype if defined($bri_switchtype); + return $self->{_bri_switchtype}; + } + ++ + sub current_dir { + my ( $self, $current_dir ) = @_; + $self->{_current_dir} = $current_dir if defined($current_dir); +@@ -102,6 +110,7 @@ + my $fe_media = $self->fe_media; + my $fe_line = $self->fe_line; + my $hwec_mode = $self->card->hwec_mode; ++ my $bri_clock_master = $self->bri_clock_master; + + + open(FH, $wanpipe_conf_template) or die "Can't open $wanpipe_conf_template"; +@@ -119,6 +128,7 @@ + $wp_file =~ s/FELINE/$fe_line/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + $wp_file =~ s/HWECMODE/$hwec_mode/g; ++ $wp_file =~ s/RMBRICLOCKMASTER/$bri_clock_master/g; + + print FH $wp_file; + close (FH); +diff -dur wancfg_zaptel/install.sh wancfg_zaptel_new/install.sh +--- wancfg_zaptel/install.sh 2007-12-18 17:59:10.000000000 -0500 ++++ wancfg_zaptel_new/install.sh 2008-01-02 11:18:51.000000000 -0500 +@@ -16,14 +16,21 @@ + mkdir -p $WAN_VIRTUAL/$WZDIR + cp -rf . $WAN_VIRTUAL/$WZDIR + +-cp -rf setup-sangoma $WAN_VIRTUAL/usr/local/sbin +-chmod 755 $WAN_VIRTUAL/usr/local/sbin/setup-sangoma ++install -D -m 755 setup-sangoma $WAN_VIRTUAL/usr/local/sbin/setup-sangoma ++install -D -m 755 wancfg_zaptel $WAN_VIRTUAL/usr/sbin/wancfg_zaptel ++install -D -m 755 wancfg_smg $WAN_VIRTUAL/usr/sbin/wancfg_smg ++install -D -m 755 wancfg_tdmapi $WAN_VIRTUAL/usr/sbin/wancfg_tdmapi + +-cp -rf wancfg_zaptel $WAN_VIRTUAL/usr/sbin +-chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_zaptel + +-cp -rf wancfg_smg $WAN_VIRTUAL/usr/sbin +-chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_smg ++#cp -rf setup-sangoma $WAN_VIRTUAL/usr/local/sbin ++#chmod 755 $WAN_VIRTUAL/usr/local/sbin/setup-sangoma + +-cp -rf wancfg_tdmapi $WAN_VIRTUAL/usr/sbin +-chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_tdmapi ++ ++#cp -rf wancfg_zaptel $WAN_VIRTUAL/usr/sbin ++#chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_zaptel ++ ++#cp -rf wancfg_smg $WAN_VIRTUAL/usr/sbin ++#chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_smg ++ ++#cp -rf wancfg_tdmapi $WAN_VIRTUAL/usr/sbin ++#chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_tdmapi +Only in wancfg_zaptel_new/templates: CVS +Only in wancfg_zaptel_new/templates/ss7_a100: CVS +Only in wancfg_zaptel_new/templates/ss7_a10u: CVS +diff -dur wancfg_zaptel/templates/wanpipe.tdm.a100 wancfg_zaptel_new/templates/wanpipe.tdm.a100 +--- wancfg_zaptel/templates/wanpipe.tdm.a100 2007-12-18 18:00:11.000000000 -0500 ++++ wancfg_zaptel_new/templates/wanpipe.tdm.a100 2008-01-02 11:18:51.000000000 -0500 +@@ -43,6 +43,7 @@ + IGNORE_FRONT_END = NO + TDMV_SPAN = TDMVSPANNO + TDMV_DCHAN = TDMVDCHAN ++TDMV_HW_DTMF = HWDTMF + + [wDEVNUMg1] + ACTIVE_CH = ALL +diff -dur wancfg_zaptel/templates/wanpipe.tdm.a200 wancfg_zaptel_new/templates/wanpipe.tdm.a200 +--- wancfg_zaptel/templates/wanpipe.tdm.a200 2007-12-18 18:00:27.000000000 -0500 ++++ wancfg_zaptel_new/templates/wanpipe.tdm.a200 2008-01-02 11:18:51.000000000 -0500 +@@ -36,6 +36,7 @@ + TTL = 255 + IGNORE_FRONT_END = NO + TDMV_SPAN = TDMVSPANNO ++TDMV_HW_DTMF = HWDTMF + + [wDEVNUMg1] + ACTIVE_CH = ALL +diff -dur wancfg_zaptel/templates/wanpipe.tdm_api.a100 wancfg_zaptel_new/templates/wanpipe.tdm_api.a100 +--- wancfg_zaptel/templates/wanpipe.tdm_api.a100 2007-12-18 18:00:44.000000000 -0500 ++++ wancfg_zaptel_new/templates/wanpipe.tdm_api.a100 2008-01-02 11:18:51.000000000 -0500 +@@ -43,6 +43,7 @@ + IGNORE_FRONT_END = NO + TDMV_SPAN = TDMVSPANNO + TDMV_DCHAN = TDMVDCHAN ++TDMV_HW_DTMF = HWDTMF + + [wDEVNUMg1] + ACTIVE_CH = ALL +diff -dur wancfg_zaptel/templates/wanpipe.tdm_api.a500 wancfg_zaptel_new/templates/wanpipe.tdm_api.a500 +--- wancfg_zaptel/templates/wanpipe.tdm_api.a500 2007-12-18 17:59:10.000000000 -0500 ++++ wancfg_zaptel_new/templates/wanpipe.tdm_api.a500 2008-01-02 11:18:51.000000000 -0500 +@@ -30,6 +30,7 @@ + PCIBUS = BUSNUM + FE_MEDIA = BRI + FE_LINE = FELINE ++RM_BRI_CLOCK_MASTER = RMBRICLOCKMASTER + TDMV_LAW = ALAW + MTU = 1500 + UDPPORT = 9000 +Only in wancfg_zaptel_new/: tmp_cfg +Only in wancfg_zaptel: .#wancfg_zaptel.1.5 +Only in wancfg_zaptel: wancfg_zaptel-3.2.pl +diff -dur wancfg_zaptel/wancfg_zaptel.pl wancfg_zaptel_new/wancfg_zaptel.pl +--- wancfg_zaptel/wancfg_zaptel.pl 2007-12-18 18:03:24.000000000 -0500 ++++ wancfg_zaptel_new/wancfg_zaptel.pl 2008-01-02 11:18:51.000000000 -0500 +@@ -9,7 +9,8 @@ + # as published by the Free Software Foundation; either version + # 2 of the License, or (at your option) any later version. + # ---------------------------------------------------------------------------- +-# Aug 22 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 ++# Jan 02 2008 2.10 David Yat Sin Added option for BRI master clock ++# Dec 15 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 + # Nov 29 2007 2.8 David Yat Sin Support for BRI cards on Trixbox + # Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option + # Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode +@@ -28,7 +29,7 @@ + system('clear'); + print "\n###################################################################"; + print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; +-print "\n# v2.9 #"; ++print "\n# v2.10 #"; + print "\n# Sangoma Technologies Inc. #"; + print "\n# Copyright(c) 2007. #"; + print "\n###################################################################\n\n"; +@@ -106,6 +107,7 @@ + my $device_has_hwec=$FALSE; + my $device_has_normal_clock=$FALSE; + my @device_normal_clocks=("0"); ++my $bri_device_has_master_clock=$FALSE; + + my $is_tdm_api=$FALSE; + +@@ -217,13 +219,16 @@ + $dchan_str="hardhdlc"; + } + } ++ + sub config_boot{ + my $script_name="wanrouter"; + my $current_run_level=3; + my $zaptel_start_level=9; + my $zaptel_stop_level=92; ++ my $network_start_level=10; + my $wanrouter_start_level=8; +- my $wanrouter_stop_level=93; ++ my $wanrouter_stop_level=91; ++ my $smg_ctrl_start_level=11; + my $command=''; + my $rc_dir=$etc_dir; + +@@ -233,7 +238,7 @@ + my $res=`cat $etc_dir/inittab |grep id`; + if ($res =~ /id:(\d+):initdefault/){ + $current_run_level=$1; +-# print "Current boot level is $current_run_level\n"; ++ print "Current boot level is $current_run_level\n"; + } else { + print "Warning: Failed to determine init boot level, assuming 3\n"; + $current_run_level=3; +@@ -307,9 +312,10 @@ + $wanrouter_start_level=$zaptel_start_level-1; + } + if ($zaptel_stop_level != 0){ +- $wanrouter_stop_level=$zaptel_stop_level+1; ++ $wanrouter_stop_level=$zaptel_stop_level-1; + } + } ++ + my $wanrouter_start_script=''; + if($wanrouter_start_level < 10){ + $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; +@@ -353,6 +359,53 @@ + return; + } + } ++ ++ if($num_bri_devices != 0){ ++ #smg_ctrl must start after network ++ print "Verifying Network boot scripts..."; ++ $command="find $rc_dir/rc".$current_run_level.".d/*network >/dev/null 2>/dev/null"; ++ if (system($command) == 0){ ++ $command="find $rc_dir/rc".$current_run_level.".d/*network"; ++ $res=`$command`; ++ if ($res =~ /.*S(\d+)network/){ ++ $network_start_level=$1; ++ print "Enabled (level:$network_start_level)\n"; ++ } else { ++ print "\nfailed to parse network boot level, assuming $network_start_level"; ++ } ++ } else { ++ print "Not installed\n"; ++ $network_start_level=0; ++ } ++ if ($network_start_level != 0 && $network_start_level > $zaptel_start_level){ ++ $smg_ctrl_start_level=$network_start_level+1; ++ print "Enabling smg_ctrl start scripts...(level:$smg_ctrl_start_level)\n"; ++ $command="install -D -m 755 /usr/sbin/smg_ctrl $rc_dir/init.d/smg_ctrl"; ++ if(system($command) !=0){ ++ print "Failed to install smg_ctrl start scripts to $rc_dir/init.d/smg_ctrl"; ++ print "smg_ctrl start scripts not installed"; ++ return; ++ } ++ my $smg_ctrl_start_script=''; ++ if($smg_ctrl_start_level < 10){ ++ $smg_ctrl_start_script="S0".$smg_ctrl_start_level."smg_ctrl"; ++ } else { ++ $smg_ctrl_start_script="S".$smg_ctrl_start_level."smg_ctrl"; ++ } ++ print "Enabling smg_ctrl boot scripts ...(level:$smg_ctrl_start_level)\n"; ++ my @run_levels= ("2","3","4","5"); ++ foreach my $run_level (@run_levels) { ++ $command="ln -sf $rc_dir/init.d/smg_ctrl ".$rc_dir."/rc".$run_level.".d/".$smg_ctrl_start_script; ++ if(system($command) !=0){ ++ print "Failed to install smg_ctrl init script to $rc_dir/rc$run_level.d/$smg_ctrl_start_script\n"; ++ print "smg_ctrl start scripts not installed\n"; ++ return; ++ } ++ } ++ } ++ ++ } ++ + } + + } +@@ -1100,6 +1153,9 @@ + + if ($card->card_model eq '500'){ + $num_bri_devices_total++; ++ if($5 eq '1'){ ++ $bri_device_has_master_clock=$FALSE; ++ } + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; +@@ -1124,9 +1180,6 @@ + } + } + if ($skip_card==$FALSE){ +-# print "A$1 port:$5 configured on slot:$3 bus:$4 span:$devnum\n"; +-# prompt_user("Press any key to continue"); +- + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + $a50x = eval {new A50x(); } or die ($@); +@@ -1136,7 +1189,7 @@ + $num_bri_devices++; + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; +- $a50x->gen_wanpipe_conf(); ++# $a50x->gen_wanpipe_conf(); + }else{ + print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; + prompt_user("Press any key to continue"); +@@ -1162,10 +1215,19 @@ + $context="from-internal"; + $group=get_bri_group(); + } ++ $a50x->gen_wanpipe_conf(); + $bri_conf.=$a50x->gen_bri_conf($bri_pos, "bri_nt" , $group, $country, $operator, $conn_type); + $woomera_conf.=$a50x->gen_woomera_conf($group, $context); + }elsif ( $dev =~ /(\d+):TE/ & $skip_card==$FALSE){ + printf("\nConfiguring port %d as TE\n", $a50x->fe_line()); ++ ++ if($bri_device_has_master_clock==$FALSE){ ++ printf("\nWould you like to use port %d as a clock source?\n", $a50x->fe_line()); ++ if(&prompt_user_list("YES","NO","") eq 'YES'){ ++ $a50x->bri_clock_master("YES"); ++ $bri_device_has_master_clock=$TRUE; ++ } ++ } + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $context; + my $group; +@@ -1174,6 +1236,7 @@ + my $country=get_bri_country(); + my $operator=get_bri_operator(); + ++ + if ($is_trixbox==$TRUE){ + $context="from-zaptel"; + $group=2; +@@ -1181,6 +1244,7 @@ + $context="from-woomera"; + $group=get_bri_group(); + } ++ $a50x->gen_wanpipe_conf(); + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); + $woomera_conf.=$a50x->gen_woomera_conf($group, $context); + } +@@ -1301,7 +1365,7 @@ + + + sub prompt_hw_dtmf { +-#HW DTMF not supported in 3.2 drivers ++#HW DTMF not supported in the 3.2 drivers + return "NO"; + print("Would you like to enable hardware DTMF detection?\n"); + my @options = ("YES","NO"); +@@ -1484,9 +1548,9 @@ + $device_has_normal_clock=$FALSE; + @device_normal_clocks = ("0"); + } +- if (!$first_cfg) { +- system('clear'); +- } ++ # if (!$first_cfg) { ++ # system('clear'); ++ # } + $first_cfg=0; + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; +Only in wancfg_zaptel: .#wancfg_zaptel.pl.1.27 +Only in wancfg_zaptel: .#wancfg_zaptel.pl.1.32 +Only in wancfg_zaptel: .wancfg_zaptel.pl.swo diff --git a/util/tmp_davidy/wancfg_zaptel-dy.tgz b/util/tmp_davidy/wancfg_zaptel-dy.tgz new file mode 100644 index 0000000..278541a Binary files /dev/null and b/util/tmp_davidy/wancfg_zaptel-dy.tgz differ diff --git a/util/tmp_davidy/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 b/util/tmp_davidy/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 new file mode 100755 index 0000000..1b96e67 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 @@ -0,0 +1,1920 @@ +#!/usr/bin/perl +# config-zaptel.pl +# Sangoma Zaptel/TDM API/SMG Configuration Script. +# +# Copyright (c) 2006, Sangoma Technologies Inc. +# +# 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. +# ---------------------------------------------------------------------------- +# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option +# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode +# Jul 20, 2007 2.5 David Yat Sin silent option +# Jun 13, 2007 Yuan Shen SS7 support +# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major +# changes to script. +# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl +# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong +# context +# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards +# Oct 13, 2006 David Yat Sin Added --opermode and --law option +# Oct 12, 2006 David Yat Sin Initial version +# ============================================================================ + +system('clear'); +print "\n###################################################################"; +print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; +print "\n# v2.7 #"; +print "\n# Sangoma Technologies Inc. #"; +print "\n# Copyright(c) 2007. #"; +print "\n###################################################################\n\n"; + +use strict; +#use warnings; +#use diagnostics; +use Card; +use A10x; +use A10u; +use A20x; +use A50x; + +my $FALSE = 1; +my $TRUE = 0; +my $zaptelprobe=' '; + +my $etc_dir=""; +my $module_list=""; +my $module_load=""; +my $module_unload=""; +my $os_type_name=""; + + +my $os_type_list=`sysctl -a |grep ostype`; +if ($os_type_list =~ m/Linux/){ + $os_type_name="Linux"; + $etc_dir="/etc"; + $module_load="modprobe"; + $module_unload="modprobe -r"; + $module_list="modprobe -l"; +}elsif ($os_type_list =~ m/FreeBSD/){ + $os_type_name="FreeBSD"; + $etc_dir="/usr/local/etc"; + $module_load="kldload"; + $module_unload="kldunload"; + $module_list="kldstat"; +}else{ + print("Failed to determine OS type\n"); + print("Exiting...\n"); + exit(1); +} + + +my $startup_string=""; +my $zaptel_conf=""; +my $zapata_conf=""; +my $bri_conf=""; +my $devnum=1; +my $current_zap_span=1; +my $current_tdmapi_span=1; +my $current_bri_span=1; +my $current_zap_channel=1; +my $num_analog_devices=0; +my $num_analog_devices_total=0; +my $num_bri_devices=0; +my $num_bri_devices_total=0; +my $num_digital_devices=0; +my $num_digital_devices_total=0; +my $num_ss7_config=0; +my $num_zaptel_config=0; +my $line_media=''; +my $max_chans=0; +my $ss7_tdmvoicechans=''; +my $ss7_array_length=0; + +my $device_has_hwec=$FALSE; +my $device_has_normal_clock=$FALSE; +my @device_normal_clocks=("0"); + +my $is_tdm_api=$FALSE; + +my $def_femedia=''; +my $def_feframe=''; +my $def_feclock=''; +my $def_bri_option=''; +my $def_signalling=''; +my $def_switchtype=''; +my $def_zapata_context=''; +my $def_zapata_group=''; +my $def_te_ref_clock=''; +my $def_tdmv_dchan=0; +my $def_bri_group=''; +my $def_felcode=''; +my $def_feframe=''; +my $def_te_sig_mode=''; + +my $def_hw_dtmf="YES"; + +my $silent_femedia="T1"; +my $silent_feframe="ESF"; +my $silent_feframe_e1="CRC4"; + +my $silent_felcode="B8ZS"; + +my $silent_feclock="NORMAL"; +my $silent_signalling="PRI CPE"; +my $silent_switchtype="National"; +my $silent_zapata_context="from-pstn"; +my $silent_zapata_group="0"; +my $silent_te_sig_mode='CCS'; + +my $def_bri_country="europe"; +my $def_bri_operator="etsi"; +my $def_bri_conn_type="Point to point"; + +my $is_trixbox = $FALSE; +my $silent = $FALSE; +my $config_zaptel = $TRUE; +my $config_zapata = $TRUE; +my $is_smg = $FALSE; + +my $tdm_api_span_num=0; +my $zaptel_installed=$FALSE; +my $modprobe_list=`$module_list`; + + +read_args(); +check_zaptel(); +my $current_dir=`pwd`; +chomp($current_dir); +my $cfg_dir='tmp_cfg'; +my $curdircfg="$current_dir"."/"."$cfg_dir"; + +unless ( -d $curdircfg ) { + $curdircfg = "mkdir " . $curdircfg; + system ($curdircfg); +} + + +my $debug_info_file="$current_dir/$cfg_dir/debug_info"; +my @hwprobe=`wanrouter hwprobe verbose`; + +my $wanpipe_conf_dir="$etc_dir/wanpipe"; +my $asterisk_conf_dir="$etc_dir/asterisk"; + +my $wanrouter_rc_template="$current_dir/templates/rc.template"; + +my $zaptel_conf_template="$current_dir/templates/zaptel.conf"; +my $zaptel_conf_file="$current_dir/$cfg_dir/zaptel.conf"; +my $zaptel_conf_file_t="$etc_dir/zaptel.conf"; + +my $zapata_conf_template="$current_dir/templates/zapata.conf"; +my $zapata_conf_file="$current_dir/$cfg_dir/zapata.conf"; +my $zapata_conf_file_t="$asterisk_conf_dir/zapata.conf"; + +my $bri_conf_template="$current_dir/templates/smg_bri.conf"; +my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; +my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; + +my $date=`date +%F`; +chomp($date); +my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; + +prepare_files(); +config_t1e1(); +config_bri(); +config_analog(); +summary(); +apply_changes(); +config_boot(); +config_ztcfg_start(); +config_smg_ctrl_start(); +clean_files(); +print "\n\n"; + + +#######################################FUNCTIONS################################################## + +sub config_boot{ + my $script_name="wanrouter"; + my $current_run_level=3; + my $zaptel_start_level=9; + my $zaptel_stop_level=92; + my $wanrouter_start_level=8; + my $wanrouter_stop_level=93; + my $command=''; + my $rc_dir=$etc_dir; + + my $res=`cat $etc_dir/inittab |grep id`; + if ($res =~ /id:(\d+):initdefault/){ + $current_run_level=$1; +# print "Current boot level is $current_run_level\n"; + } else { + print "Warning: Failed to determine init boot level, assuming 3\n"; + $current_run_level=3; + } + + + print "\nWanrouter boot scripts configuration...\n\n"; + print "Removing existing $script_name boot scripts..."; + $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; + if(system($command) == 0){ + print "OK\n"; + } else { + print "Not installed\n"; + } + if($num_ss7_config!=0){ + $script_name="smgss7_ctrl"; + } + + print ("Would you like $script_name to start on system boot?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + #examine system bootstrap files + $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$rc_dir; + } else { + $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$etc_dir."/rc.d"; + } else { + print "Failed to locate boostrap directory\n"; + print "wanrouter boot scripts will not be installed\n"; + return; + } + } + + if($zaptel_installed==$TRUE){ + print "Verifying Zaptel boot scripts..."; + #find zaptel start scripts + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; + $res=`$command`; + if ($res =~ /.*S(\d+)zaptel/){ + $zaptel_start_level=$1; + print "Enabled (level:$zaptel_start_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_start_level"; + } + } else { + print "Not installed\n"; + $zaptel_start_level=0; + } + + #find zaptel stop scripts + print "Verifying Zaptel shutdown scripts..."; + $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find ".$rc_dir."/rc6.d/*zaptel"; + $res=`$command`; + if ($res =~ /.*K(\d+)zaptel/){ + $zaptel_stop_level=$1; + print "Enabled (level:$zaptel_stop_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; + } + } else { + print "Not installed\n"; + $zaptel_stop_level=0; + } + if ($zaptel_start_level != 0){ + $wanrouter_start_level=$zaptel_start_level-1; + } + if ($zaptel_stop_level != 0){ + $wanrouter_stop_level=$zaptel_stop_level+1; + } + } + my $wanrouter_start_script=''; + if($wanrouter_start_level < 10){ + $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; + } else { + $wanrouter_start_script="S".$wanrouter_start_level.$script_name; + } + my $wanrouter_stop_script=''; + if($wanrouter_stop_level < 10){ + $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; + } else { + $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; + } + + $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; + if(system($command) !=0){ + $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; + if(system($command) !=0){ + print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; + print "$script_name boot scripts not installed\n"; + return; + } + } + print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; + if(system($command) !=0){ + print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; + print "$script_name start scripts not installed\n"; + return; + } + } + + print "Enabling wanrouter shutdown scripts ...(level:$wanrouter_stop_level)\n"; + @run_levels= ("0","1","6"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; + if(system($command) !=0){ + print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; + print "$script_name stop scripts not installed\n"; + return; + } + } + } + +} + + +sub config_ztcfg_start{ + if ($num_zaptel_config ==0){ + return; + } + my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) != 0){ + #Zaptel init scripts not installed, prompt for wanpipe_zaptel_start_script + print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + exec_command("cp -f $current_dir/templates/zaptel_start_script $wanpipe_conf_dir/scripts/start"); + } + } +} + +sub config_smg_ctrl_start{ + if($num_bri_devices == 0){ + return; + } + print ("Would you like smg_ctrl to start on wanrouter start?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite + my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; + } else { + $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; + } + if (system($command) == 0){ + print "smgbri start script installed successfully"; + } else { + print "failed to install smgbri start script"; + } + } +} + +sub check_zaptel{ + if ($modprobe_list =~ /zaptel.ko/){ + $zaptel_installed=$TRUE; + } +} + +sub apply_changes{ + my $asterisk_command=''; + my $bri_command=''; + my $asterisk_restart=$FALSE; + my $res=''; + + system('clear'); + + if($silent==$TRUE){ + $res="Stop now"; + }elsif($is_tdm_api==$TRUE){ + print "\n Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", + "Do not save cfg: Exit", + ""); + }else{ + print "\nZaptel and Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", + "Save cfg: Restart Asterisk & Wanpipe when convenient", + "Save cfg: Stop Asterisk & Wanpipe now", + "Save cfg: Stop Asterisk & Wanpipe when convenient", + "Do not save cfg: Exit", + ""); + } + + + if ($res =~ m/Exit/){ + print "No changes made to your configuration files\n"; + exit 0; + } + if ($res =~ m/now/){ + $asterisk_command='stop now'; + } else { + $asterisk_command='stop when convenient'; + } + + if ($res =~ m/Restart/){ + $asterisk_restart=$TRUE; + } else { + $asterisk_restart=$FALSE; + } + + if ($is_trixbox==$TRUE){ + exec_command("amportal stop"); + unload_zap_modules(); + } elsif ($is_tdm_api==$FALSE ){ + if (`(pidof asterisk)` != 0 ){ + print "\nStopping Asterisk...\n"; + exec_command("asterisk -rx \"$asterisk_command\""); + sleep 2; + while (`(pidof asterisk)` != 0 ){ + if ($asterisk_command eq "stop now"){ + print "Failed to stop asterisk using command: \'$asterisk_command\' \n"; + my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes"); + my $res=&prompt_user_list(@options,""); + + if ( $res =~ m/Force Stop/){ + execute_command("kill -KILL \$(pidof asterisk)"); + } elsif ( $res =~ m/Exit/ ){ + exit(1); + } else { + print "Waiting for asterisk to stop...\n"; + sleep 5; + exec_command("asterisk -rx \"$asterisk_command\""); + } + } else { + #stop when convenient option was selected + print "Waiting for asterisk to stop...\n"; + sleep 3; + } + } + + + + + + }else { + print "\nAsterisk is not running...\n"; + } + + } + + if($num_bri_devices != 0){ + exec_command("/usr/sbin/smg_ctrl stop"); + } + + print "\nStopping Wanpipe...\n"; + exec_command("wanrouter stop all"); + + if ($zaptel_installed==$TRUE){ + if($is_tdm_api==$FALSE){ + print "\nUnloading Zaptel modules...\n"; + unload_zap_modules(); + } + } + + print "\nRemoving old configuration files...\n"; + + exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); + + gen_wanrouter_rc(); + + print "\nCopying new Wanpipe configuration files...\n"; + copy_config_files(); + if($num_bri_devices != 0){ + print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; + exec_command("cp -f $bri_conf_file $bri_conf_file_t"); + } + + if ($zaptel_installed==$TRUE){ + if($config_zaptel==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; + exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); + } + } + } + + if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ + print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; + exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); + } + + if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ + print "\nStarting Wanpipe...\n"; + exec_command("wanrouter start"); + + if($num_bri_devices != 0){ + print "Loading SMG BRI...\n"; + sleep 2; + exec_command("/usr/sbin/smg_ctrl start"); + } + +# if ( ! -e "/$wanpipe_conf_dir/scripts/start" & $is_trixbox==$FALSE && $is_smg==$FALSE ){ + if ($num_zaptel_config != 0){ + print "Loading Zaptel...\n"; + sleep 2; + exec_command("ztcfg -v"); +# print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); +# if (&prompt_user_list("YES","NO","") eq 'YES'){ +# exec_command("cp -f $wanpipe_conf_dir/samples/wanpipe_zaptel_start $wanpipe_conf_dir/scripts/start"); +# } + } + if ($is_trixbox==$TRUE){ + print "\nStarting Amportal...\n"; + exec_command("amportal start"); + sleep 2; + }elsif($config_zapata==$TRUE){ + print "\nStarting Asterisk...\n"; + exec_command("asterisk"); + sleep 2; + + print "\nListing Asterisk channels...\n\n"; + exec_command("asterisk -rx \"zap show channels\""); + print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; + }else{ + } + } + print "\nWanrouter start complete...\n"; +} + + + +sub save_debug_info{ + my $version=`wanrouter version`; + chomp($version); + + my $uname=`uname -a`; + chomp($uname); + + my $issue=''; + + if ($os_type_list =~ m/Linux/){ + $issue=`cat $etc_dir/issue`; + chomp($issue); + } + + my $debug_info="\n"; + $debug_info.="===============================================================\n"; + $debug_info.=" SANGOMA DEBUG INFO FILE \n"; + $debug_info.=" Generated on $date \n"; + $debug_info.="===============================================================\n"; + + $debug_info.="\n\nwanrouter hwprobe\n"; + $debug_info.="@hwprobe\n"; + $debug_info.="\nwanrouter version\n"; + $debug_info.="$version\n"; + $debug_info.="\nKernel \"uname -a\"\n"; + $debug_info.="$uname\n"; + if ($os_type_list =~ m/Linux/){ + $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; + $debug_info.="$issue\n"; + } + $debug_info.="EOF\n"; + + open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; + print FH $debug_info; + close (FH); + exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); +} + + + + + + + + + +sub get_zapata_context{ + my ($card_model,$card_port)=@_; + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("Select dialplan context for A%s on port %s\n", $card_model, $card_port); + my $res = &prompt_user_list(@options,$def_zapata_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_zapata_context); + } + + $context=$res_context; + }elsif($res eq $def_zapata_context){ + $context=$def_zapata_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + $context=$silent_zapata_context; + } + $def_zapata_context=$context; + return $context; +} + +sub gen_wanrouter_rc{ + #update wanpipe startup sequence + my $rcfile=""; + if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { + open (FH,"$wanrouter_rc_template"); + } + while () { + $rcfile .= $_; + } + close (FH); + open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); + $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; + print FH $rcfile; + close (FH); +} + +sub prepare_files{ + + if ($is_trixbox==$TRUE){ + $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; + $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; + $zapata_conf_file_t="$asterisk_conf_dir/zapata-auto.conf"; + } + + if ($silent==$FALSE){ + if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ + print "Would you like to generate $zapata_conf_file_t\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $config_zapata = $FALSE; + } + } + } + +#remove temp files + exec_command("rm -f $current_dir/$cfg_dir/*"); + +#backup existing configuration files + exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); + exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); + +} + +sub clean_files{ + exec_command("rm -rf $current_dir/$cfg_dir"); +} + + +sub write_zapata_conf{ + my $zp_file=""; + open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + + $zp_file.=$zapata_conf; + + open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; + print FH $zp_file; + close(FH); +} + +sub copy_config_files{ + my @wanpipe_files = split / /, $startup_string; + exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc $wanpipe_conf_dir"); + foreach my $wanpipe_file (@wanpipe_files) { + exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf $wanpipe_conf_dir"); + } +} + + + + + + + + + + + + +sub unload_zap_modules{ + my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); + foreach my $module (@modules_list) { + if ($modprobe_list =~ m/$module/){ + exec_command("$module_unload -r $module"); + } + } +} + +sub write_zaptel_conf{ + my $zp_file=""; + open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + $zp_file=$zp_file.$zaptel_conf; + open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; + print FH $zp_file; + close(FH); +} + +sub summary{ + if($devnum==1){ + system('clear'); + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); + exit 0; + }else{ + if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ + write_zaptel_conf(); + } + if ($num_bri_devices != 0 ){ + write_bri_conf(); + } + if ($config_zapata==$TRUE){ + write_zapata_conf(); + } + save_debug_info(); + system('clear'); + my $file_list = 1; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); + print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); + print(" $num_bri_devices_total ISDN BRI card(s) detected, $num_bri_devices configured\n"); + + print "\nConfigurator has created the following files:\n"; + print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; + $file_list++; + + if ($num_bri_devices != 0){ + print "\t$file_list. sangoma_brid config file $wanpipe_conf_dir/smg_bri\n"; + $file_list++; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; + } + + if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ + print "\n\nYour original configuration files will be saved to:\n"; + $file_list=1; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. $zaptel_conf_file_t.bak \n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. $zapata_conf_file_t.bak \n\n"; + } + + print "\nYour configuration has been saved in $debug_tarball.\n"; + print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } +} + + +sub exec_command{ + my @command = @_; + if (system(@command) != 0 ){ + print "Error executing command:\n@command\n\n"; + } + return $?; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "def=\"$defaultValue\": "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $defaultValue = @list[$#list]; + + my $i; + my $valid = 0; + for $i (0..$#list-1) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + my $list_sz = $#list; + print "[1-$list_sz"; + if ( ! $defaultValue eq ''){ + print ", ENTER=\'$defaultValue\']:"; + }else{ + print "]:"; + } + $| = 1; + $_ = ; + chomp; + if ( $_ eq '' & ! $defaultValue eq ''){ + print "\n"; + return $defaultValue; + } + + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $list_sz) { + print "\nError: Invalid option, input a value between 1 and $list_sz \n"; + } else { + print "\n"; + return @list[$1-1] ; + } + } else { + print "\nError: Invalid option, input an integer\n"; + } + } +} + +sub read_args { + my $arg_num; + foreach $arg_num (0 .. $#ARGV) { + $_ = $ARGV[$arg_num]; + if( /^--trixbox$/){ + $is_trixbox=$TRUE; + }elsif ( /^--tdm_api/){ + $is_tdm_api=$TRUE; + }elsif ( /^--smg$/){ + $is_smg=$TRUE; + }elsif ( /^--silent$/){ + $silent=$TRUE; + }elsif ( /^--no-zapata$/){ + $config_zapata=$FALSE; + }elsif ( /^--no-zaptel$/){ + $config_zaptel=$FALSE; + }elsif ( $_ =~ /--fe_media=(\w+)/){ + $silent_femedia=$1; + if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ + printf("Invalid value for fe_media, should be T1/E1\n"); + exit(1); + } + }elsif ( $_ =~ /--fe_frame=(\w+)/){ + $silent_feframe=$1; + if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ + printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); + exit(1); + } + }elsif ( $_ =~ /--fe_clock=(\w+)/){ + $silent_feclock=$1; + if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ + printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); + exit(1); + } + }elsif ( $_ =~ /--signalling=(\w+)/){ + my $tmp_signalling=$1; + if ($tmp_signalling eq 'em'){ + $silent_signalling="E & M"; + }elsif ($tmp_signalling eq 'em_w'){ + $silent_signalling="E & M Wink"; + }elsif ($tmp_signalling eq 'pri_cpe'){ + $silent_signalling="PRI CPE"; + }elsif ($tmp_signalling eq 'pri_net'){ + $silent_signalling="PRI NET"; + }elsif ($tmp_signalling eq 'fxs_ls'){ + $silent_signalling="FXS - Loop Start"; + }elsif ($tmp_signalling eq 'fxs_gs'){ + $silent_signalling="FXS - Ground Start"; + }elsif ($tmp_signalling eq 'fxs_ks'){ + $silent_signalling="FXS - Kewl Start"; + }elsif ($tmp_signalling eq 'fxo_ls'){ + $silent_signalling="FXO - Loop Start"; + }elsif ($tmp_signalling eq 'fxo_gs'){ + $silent_signalling="FXO - Ground Start"; + }elsif ($tmp_signalling eq 'fxo_ks'){ + $silent_signalling="FXO - Kewl Start"; + }else{ + printf("Invalid option for --signalling, options are\n"); + printf("\t pri_cpe/pri_net/em/em_w\n"); + printf("\t em/em_w\n"); + printf("\t fxo_ls/fxo_gs/fxo_ks\n"); + printf("\t fxs_ls/fxs_gs/fxs_ks\n"); + exit(1); + } + }elsif ( $_ =~ /--conf_dir=(.*)/){ + $etc_dir=$1; + if (! -d $etc_dir){ + printf("Error: directory $1 does not exist\n"); + exit(1); + } + } + } + + if ($is_trixbox==$TRUE){ + print "\nGenerating configuration files for Trixbox\n"; + } + if ($is_smg==$TRUE){ + print "\nGenerating configuration files for SS7\n"; + } + if ($is_tdm_api==$TRUE){ + $config_zapata = $FALSE; + } + +} + +#------------------------------BRI FUNCTIONS------------------------------------# +sub get_bri_country { + $def_bri_country = "europe"; + return $def_bri_country; +} + +sub get_bri_group{ + my $group; + my $res_group=&prompt_user("\nInput the group for this port\n",$def_bri_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ + print "Invalid group, input an integer greater than 0\n"; + $res_group=&prompt_user("Input the group for this port",$def_bri_group); + } + $group=$res_group; + $def_bri_group=$group; + return $def_bri_group; +} + + +sub get_bri_operator { +#warning returning ETSI + $def_bri_operator = "etsi"; + return $def_bri_operator; + + + + my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", + "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", + "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); + + my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); + + my $res = &prompt_user_list(@options,$def_switchtype); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_operator=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + +sub write_bri_conf{ + my $bri_file=""; + open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; + while () { + $bri_file .= $_; +} + close (FH); + $bri_file=$bri_file.$bri_conf; + open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; + print FH $bri_file; + close(FH); +} + + +sub get_bri_conn_type{ + my $conn_type; + + my @options = ( "Point to multipoint", "Point to point"); + my @options_val = ("point_to_multipoint", "point_to_point"); + + my $res = &prompt_user_list(@options,$def_bri_conn_type); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_conn_type=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid BRI connection type\n"; + exit 1; +} + + + + +sub config_bri{ + if($is_smg!=$TRUE){ + return; + } + my $a50x; + system('clear'); + print "------------------------------------\n"; + print "Configuring ISDN BRI cards [A500]\n"; + print "------------------------------------\n"; + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ + $skip_card=$FALSE; + if ($1 eq '500'){ + my $card = eval {new Card(); } or die ($@); + + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->span_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + + my $hwec=0; + if($6 gt 0){ + $hwec=1; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + + if ($card->card_model eq '500'){ + $num_bri_devices_total++; + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + + if($is_trixbox==$FALSE){ +select_bri_option: + print "\nWould you like to configure A$1 port $5 on slot:$3 bus:$4\n"; + my @options=("YES", "NO", "Exit"); + $def_bri_option=&prompt_user_list(@options,$def_bri_option); + if($def_bri_option eq 'YES'){ + $skip_card=$FALSE; + $bri_conf.="\n;Sangoma A$1 port $5 [slot:$3 bus:$4 span:$devnum]"; + }elsif($def_bri_option eq 'NO'){ + $skip_card=$TRUE; + }else{ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } else { + goto select_bri_option; + } + } + } + if ($skip_card==$FALSE){ +# print "A$1 port:$5 configured on slot:$3 bus:$4 span:$devnum\n"; +# prompt_user("Press any key to continue"); + + $startup_string.="wanpipe$devnum "; + $a50x = eval {new A50x(); } or die ($@); + $a50x->card($card); + $a50x->fe_line($5); + $devnum++; + $num_bri_devices++; + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + $a50x->gen_wanpipe_conf(); + }else{ + print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; + prompt_user("Press any key to continue"); + } + + } + } + }elsif ( $dev =~ /(\d+):NT/ & $skip_card==$FALSE){ + printf("\nConfiguring port %d as NT\n", $a50x->fe_line()); + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $bri_pos=$current_bri_span; + + $current_bri_span=$current_bri_span+1; + my $conn_type=get_bri_conn_type(); + my $group=get_bri_group(); + my $country=get_bri_country(); + + my $operator=get_bri_operator(); + $bri_conf.=$a50x->gen_bri_conf($bri_pos, "bri_nt" , $group, $country, $operator, $conn_type); + }elsif ( $dev =~ /(\d+):TE/ & $skip_card==$FALSE){ + printf("\nConfiguring port %d as TE\n", $a50x->fe_line()); + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $bri_pos=$current_bri_span; + + $current_bri_span=$current_bri_span+1; + my $conn_type=get_bri_conn_type(); + my $group=get_bri_group(); + my $country=get_bri_country(); + + my $operator=get_bri_operator(); + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); + } + } + prompt_user("Press any key to continue"); + if($num_bri_devices_total!=0){ + print("\nISBN BRI card configuration complete\n\n"); + prompt_user("Press any key to continue"); + } +} + + + + + +#------------------------------T1/E1 FUNCTIONS------------------------------------# + +sub get_te_ref_clock{ + my @list_normal_clocks=@_; + my @f_list_normal_clocks; + my $f_port; + foreach my $port (@list_normal_clocks) { + if ($port eq '0'){ + $f_port = "Free run"; +} else { + $f_port = "Port ".$port; +} + push(@f_list_normal_clocks, $f_port); +} + + my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); + my $i; + + for $i (0..$#f_list_normal_clocks){ + if ( $res eq @f_list_normal_clocks[$i] ){ + return @list_normal_clocks[$i]; +} +} + + print "Internal error: Invalid reference clock\n"; + exit 1; + +} + + +sub prompt_user_hw_dchan{ + my ($card_model, $port, $port_femedia) = @_; + my $res_dchan=''; + my $dchan; + + printf("Hardware HDLC can be performed on the data channel.\n"); +prompt_hw_dchan: + my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); + while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ + print "Invalid channel, input an integer (0 for unused).\n"; + $res_dchan=&prompt_user("Select the data channel","0"); + } + if ( $res_dchan < 0){ + printf("Error: channel cannot have negative value\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ( $port_femedia eq 'T1' && $res_dchan > 24){ + printf("Error: only 24 channels available on T1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + }elsif ($port_femedia eq 'E1' && $res_dchan > 31){ + printf("Error: only 31 channels available on E1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ($res_dchan == 0){ + printf("HW HDLC channel not used\n"); + }else{ + printf("HW HDLC channel set to:%d\n", $res_dchan); + } + return $res_dchan; +} + + + +sub get_zapata_group{ + my ($card_model,$card_port,$context)=@_; + my $group=''; + if($is_trixbox==$TRUE){ + if($context eq "from-zaptel"){ + $group=0; + return $group; + }elsif($context eq "from-internal"){ + $group=1; + return $group; + }else{ + print "Internal error:invalid group for Trixbox\n"; + } + }else{ + if($context eq "from-pstn"){ + $group=0; + }elsif($context eq "from-internal"){ + $group=1; + }else{ + my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)){ + print "Invalid group, input an integer.\n"; + $res_group=&prompt_user("Input the group for this port",$def_zapata_group); + } + $group=$res_group; + $def_zapata_group=$group; + } + } + + return $group; +} + + + +sub prompt_hw_dtmf { + print("Would you like to enable hardware DTMF detection?\n"); + my @options = ("YES","NO"); + $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); + return $def_hw_dtmf; + +} + +sub get_pri_switchtype { + my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); + my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); + my $res = &prompt_user_list(@options,$def_switchtype); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_switchtype=@options[$i]; + return @options_val[$i]; +} +} + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + + +sub gen_ss7_voicechans{ + my @ss7_array = @_; + my $T1CHANS = pop(@ss7_array); + my $count = @ss7_array; + my $output =''; + my $chan_in = 1; + my $chan_de = 0; + my $flag = 0; + my $i = 0; + my $j = 0; + + while($i < $count){ + $j = $i + 1; + if ($ss7_array[$i] > 2 && $i == 0){ + $chan_de = $ss7_array[$i] - 1; + $output .= "1-$chan_de"; + $flag = 1; + }elsif ($ss7_array[$i] == 2 && $i == 0){ + $output .= "1"; + $flag = 1; + } + + if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ + goto Incrementing; + }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ + goto Incrementing; + } + + if ($i < ($count-1)){ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < ($ss7_array[$j]-1)){ + $chan_de = $ss7_array[$j] - 1; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$chan_in"; + }else{ + $output .= "$chan_in"; + $flag = 1; + } + } + }else{ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < $T1CHANS){ + $chan_de = $T1CHANS; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$T1CHANS"; + }else{ + $output .= "$T1CHANS"; + $flag = 1; + } + } + } + +Incrementing: + $i++; + } + return $output; +} + +sub prompt_user_ss7_chans{ + my @ss7_string = @_; + my $def_ss7_group_chan = ''; + + my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + +CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ + print("ERROR: Invalid channel number, input an integer only.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); +} + if ($line_media eq 'T1'){ + while ($ss7_group_chan>24 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 24 channels in T1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +}elsif ($line_media eq 'E1'){ + while ($ss7_group_chan>31 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 31 channels in E1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +} + return $ss7_group_chan; +} + + + + + + +sub config_t1e1{ + system('clear'); + print "---------------------------------------------\n"; + print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; + print "---------------------------------------------\n"; + + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + + if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ + #do not count analog devices + $num_digital_devices_total++; + } + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->span_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + + my $hwec=0; + if ( $dev =~ /HWEC=(\d+)/){ + if($1 gt 0){ + $hwec=1; + } + } + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + my $port=$6; + if ($6 eq 'PRI') { + $port=$5; + } + + if ( $card->card_model eq '101' | + $card->card_model eq '102' | + $card->card_model eq '104' | + $card->card_model eq '108' ){ + system('clear'); + if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ + print "A$1 detected on slot:$3 bus:$4\n"; + $device_has_normal_clock=$FALSE; + @device_normal_clocks = ("0"); + } + system('clear'); + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; + print "$msg"; + print "-----------------------------------------------------------\n"; + my $fe_media = ''; + if ($silent==$TRUE){ + $fe_media = $silent_femedia; + } else { + printf ("\nSelect media type for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + my @options = ("T1", "E1", "Unused","Exit"); + $fe_media = prompt_user_list( @options, $def_femedia); + } + + if ( $fe_media eq 'Exit'){ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } + }elsif ( $fe_media eq 'Unused'){ + $def_femedia=$fe_media; + my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; + print "$msg"; + prompt_user("Press any key to continue"); + }else{ + if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ + $device_has_hwec=$TRUE; + } + + $def_femedia=$fe_media; + $startup_string.="wanpipe$devnum "; + my $a10x; + + if ($1 !~ m/104/ && $2 !~ m/SH/) { + $a10x = eval {new A10u(); } or die ($@); + $a10x->card($card); + if ($5 eq "A") { + $a10x->fe_line("1"); + } else { + $a10x->fe_line("2"); + } + } else { + $a10x = eval {new A10x(); } or die ($@); + if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + $a10x->card($card); + $a10x->fe_line($6); + } + + $card->first_chan($current_zap_channel); + $a10x->fe_media($fe_media); + if ( $fe_media eq 'T1' ){ + $current_zap_channel+=24; + $max_chans = 24; + $line_media = 'T1'; + + $def_te_sig_mode=''; + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s.\n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe, + $port); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("B8ZS", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("ESF", "D4"); + $def_feframe= &prompt_user_list(@options, $def_feframe); + } + + + } else { + $def_felcode=$silent_felcode; + } + + + }else{ #fe_media = E1 + $current_zap_channel+=31; + $max_chans = 31; + $line_media = 'E1'; + + + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("HDB3", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("CRC4", "NCRC4","UNFRAMED"); + $def_feframe = &prompt_user_list(@options, $def_feframe); + +# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); +# my @options = ("CCS - Clear channel signalling ", "CAS"); +# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); + + } + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + } else { + $def_te_sig_mode="CAS"; + } + + + } else { + $def_felcode=$silent_felcode; + } + + + } + $a10x->fe_lcode($def_felcode); + $a10x->fe_frame($def_feframe); + $a10x->te_sig_mode($def_te_sig_mode); + if($silent==$FALSE){ + my @options = ("NORMAL", "MASTER"); + printf ("Select clock for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_feclock=&prompt_user_list(@options, $def_feclock); + } else { + $def_feclock=$silent_feclock; + } + + $a10x->fe_clock($def_feclock); + if ( $def_feclock eq 'NORMAL') { + $device_has_normal_clock=$TRUE; + push(@device_normal_clocks, $a10x->fe_line); + } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ + printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", + $card->card_model, + $port, + $card->pci_slot, + $card->pci_bus); + printf(" Free run: Use internal oscillator on card [default] \n"); + printf(" Port N: Sync with clock from port N \n\n"); + + printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); + $a10x->te_ref_clock($def_te_ref_clock); + } + + my @options=""; + if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ +# if ($is_smg==$TRUE && ($zaptelprobe =~ /zaptel.ko/)){ + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_smg==$TRUE && $zaptel_installed==$FALSE){ +# } elsif ($is_smg==$TRUE && ($zaptelprobe !~ /zaptel.ko/)){ + @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_tdm_api==$TRUE){ + $def_signalling="TDM API"; + } else { + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); + } + if ($silent==$FALSE){ + if( $is_tdm_api == $FALSE){ + printf ("Select signalling type for %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_signalling=&prompt_user_list(@options,$def_signalling); + } + } else { + $def_signalling=$silent_signalling; + } + $a10x->signalling($def_signalling); + + + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + } + + my $ss7_chan; + my $ss7_group_start; + my $ss7_group_end; + my @ss7_chan_array; + my @ss7_sorted; + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_option(1); + print("Choose an option below to configure SS7 signalling channels:\n"); + my @options =("Configure consecutive signalling channels(e.g #1-#16)", + "Configure separate signalling channels(e.g #1,#10)"); + my $res = &prompt_user_list(@options, ""); + if ( $res eq 'Configure separate signalling channels(e.g #1,#10)'){ + goto SS7CHAN; + while (1){ + print("\nAny other SS7 signalling channel to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7CHAN: + $ss7_chan = prompt_user_ss7_chans('Specify the time slot for SS7 signalling(24 for T1? 16 for E1?)'); + push(@ss7_chan_array, $ss7_chan); + $ss7_array_length = @ss7_chan_array; + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + }else{ + goto SS7GROUP; + while(1){ + print("\nAny other SS7 consecutive signalling channels to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7GROUP: + $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); + $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); + if ($ss7_group_start > $ss7_group_end){ + print("The starting channel number is bigger than the ending one!\n"); + goto SS7GROUP; + } + my $i = 0; + for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ + push(@ss7_chan_array, $i); + my @remove_duplicate; + @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); + $ss7_array_length = @ss7_chan_array; + + if ($ss7_array_length > $max_chans){ + print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); + + @ss7_chan_array = (); + goto SS7GROUP; + } + } + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + } + +ENDSS7CONFIG: + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); + my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); + $ss7_tdmvoicechans = $ss7_voicechans; + + if ($ss7_voicechans =~ m/(\d+)/){ + $a10x->ss7_tdminterface($1); + } + + $a10x->ss7_tdmchan($ss7_voicechans); + $num_ss7_config++; + }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ + $a10x->ss7_option(2); + $num_ss7_config++; + }elsif ($a10x->signalling eq 'TDM API'){ + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); + } + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + }else{ + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + } + + + if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ + if ($silent==$FALSE && $config_zapata==$TRUE){ + printf ("Select switchtype for %s on port %s \n", $card->card_model, $port); + $a10x->pri_switchtype(get_pri_switchtype()); + } else { + $a10x->pri_switchtype($silent_switchtype); + } + } + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_subinterface(1); + $a10x->gen_wanpipe_ss7_subinterfaces(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(2); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + my $ss7_element; + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + + $a10x->gen_wanpipe_conf(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + }else{ + $a10x->gen_wanpipe_conf(); + } + + if ($is_smg==$TRUE && $config_zapata==$FALSE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' + | $a10x->signalling eq 'No Signaling (Voice Only)')){ + } + $zaptel_conf.=$a10x->gen_zaptel_conf(); + }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ + + $zaptel_conf.=$a10x->gen_zaptel_conf(); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + } + }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + $zaptel_conf.=$a10x->gen_zaptel_conf(); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + }elsif ($is_tdm_api == $FALSE){ + $zaptel_conf.=$a10x->gen_zaptel_conf(); + } + $devnum++; + $num_digital_devices++; + my $msg ="\n\nPort ".$port." on A".$card->card_model." configuration complete...\n"; + print "$msg"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + } + } + + } + } + if($num_digital_devices_total!=0){ + print("\nT1/E1 card configuration complete.\n"); + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } +# close SCR; +} + + +#------------------------------ANALOG FUNCTIONS------------------------------------# + + +sub config_analog{ + my $a20x; + system('clear'); + print "------------------------------------\n"; + print "Configuring analog cards [A200/A400]\n"; + print "------------------------------------\n"; + + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ + $skip_card=$FALSE; + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->span_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + my $hwec=$7; + if ($hwec==0){ + $card->hwec_mode('NO'); + } + else{ + $card->hwec_mode('YES'); + } + if ($card->card_model eq '200' | $card->card_model eq '400'){ + $num_analog_devices_total++; + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + if($is_trixbox==$FALSE){ + print "\nWould you like to configure A$1 on slot:$3 bus:$4\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $skip_card=$TRUE; + } + } + if ($skip_card==$FALSE){ + print "A$1 configured on slot:$3 bus:$4 span:$devnum\n"; + prompt_user("Press any key to continue"); + $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; + $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; + $startup_string.="wanpipe$devnum "; + + $a20x = eval {new A20x(); } or die ($@); + $a20x->card($card); + $card->first_chan($current_zap_channel); + $current_zap_channel+=24; + my $i; + $devnum++; + $num_analog_devices++; + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + $a20x->gen_wanpipe_conf(); + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + } + }else{ + print "A$1 on slot:$3 bus:$4 not configured\n"; + prompt_user("Press any key to continue"); + } + } + }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-internal"); + $a20x->card->zap_group("1"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); + }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-zaptel"); + $a20x->card->zap_group("0"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); + } + } + if($num_analog_devices_total!=0){ + print("\nAnalog card configuration complete\n\n"); + prompt_user("Press any key to continue"); + } + +} + diff --git a/util/tmp_davidy/wancfg_zaptel/A10u.pm b/util/tmp_davidy/wancfg_zaptel/A10u.pm new file mode 100644 index 0000000..c0536af --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/A10u.pm @@ -0,0 +1,417 @@ +#class A10u +#for A101/2/u/c series cards + +package A10u; +use Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _card => undef, + _fe_line => undef, + _fe_media => 'T1', + _fe_lcode => 'B8ZS', + _fe_frame => 'ESF', + _fe_clock => 'NORMAL', + _te_sig_mode => undef, + _te_ref_clock => '0', + _signalling => 'PRI_CPE', + _pri_switchtype => 'national', + _hw_dchan => '0', + _ss7_sigchan => undef, + _ss7_option => undef, + _ss7_tdmchan => undef, + _ss7_subinterface => undef, + _ss7_tdminterface => undef, + }; + bless $self, $class; + return $self; +} + +sub card { + my ( $self, $card ) = @_; + $self->{_card} = $card if defined($card); + return $self->{_card}; +} +sub fe_line { + my ( $self, $fe_line ) = @_; + $self->{_fe_line} = $fe_line if defined($fe_line); + return $self->{_fe_line}; +} +sub te_ref_clock { + my ( $self, $te_ref_clock ) = @_; + $self->{_te_ref_clock} = $te_ref_clock if defined($te_ref_clock); + return $self->{_te_ref_clock}; +} +sub signalling { + my ( $self, $signalling ) = @_; + $self->{_signalling} = $signalling if defined($signalling); + return $self->{_signalling}; +} + +sub fe_media { + my ( $self, $fe_media ) = @_; + $self->{_fe_media} = $fe_media if defined($fe_media); + return $self->{_fe_media}; +} + +sub fe_lcode { + my ( $self, $fe_lcode) = @_; + $self->{_fe_lcode} = $fe_lcode if defined($fe_lcode); + return $self->{_fe_lcode}; +} + +sub te_sig_mode { + my ( $self, $te_sig_mode ) = @_; + $self->{_te_sig_mode} = $te_sig_mode if defined($te_sig_mode); + return $self->{_te_sig_mode}; +} + + +sub fe_frame { + my ( $self, $fe_frame ) = @_; + $self->{_fe_frame} = $fe_frame if defined($fe_frame); + return $self->{_fe_frame}; +} + +sub fe_clock { + my ( $self, $fe_clock ) = @_; + $self->{_fe_clock} = $fe_clock if defined($fe_clock); + return $self->{_fe_clock}; +} + +sub pri_switchtype { + my ( $self, $pri_switchtype ) = @_; + $self->{_pri_switchtype} = $pri_switchtype if defined($pri_switchtype); + return $self->{_pri_switchtype}; +} + +sub ss7_option { + my ( $self, $ss7_option ) = @_; + $self->{_ss7_option} = $ss7_option if defined($ss7_option); + return $self->{_ss7_option}; +} + +sub ss7_sigchan { + my ( $self, $ss7_sigchan ) = @_; + $self->{_ss7_sigchan} = $ss7_sigchan if defined($ss7_sigchan); + return $self->{_ss7_sigchan}; +} + +sub ss7_tdmchan { + my ( $self, $ss7_tdmchan ) = @_; + $self->{_ss7_tdmchan} = $ss7_tdmchan if defined($ss7_tdmchan); + return $self->{_ss7_tdmchan}; +} + +sub ss7_subinterface { + my ( $self, $ss7_subinterface ) = @_; + $self->{_ss7_subinterface} = $ss7_subinterface if defined($ss7_subinterface); + return $self->{_ss7_subinterface}; +} + +sub ss7_tdminterface { + my ( $self, $ss7_tdminterface ) = @_; + $self->{_ss7_tdminterface} = $ss7_tdminterface if defined($ss7_tdminterface); + return $self->{_ss7_tdminterface}; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $i; + my $valid = 0; + for $i (0..$#list) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $#list+1) { + print "Invalid option: Value out of range \n"; + } else { + return $1-1 ; + } + } else { + print "Invalid option: Input an integer\n"; + } + } +} + +sub print { + my ($self) = @_; + $self->card->print(); + printf (" fe_line: %s\n fe_media: %s\n fe_lcode: %s\n fe_frame: %s \n fe_clock:%s\n ", $self->fe_line, $self->fe_media, $self->fe_lcode, $self->fe_frame, $self->fe_clock); + +} + +sub gen_wanpipe_ss7_subinterfaces{ + my ($self) = @_; + my $wanpipe_ss7_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + my $ss7_sigchan = $self->ss7_sigchan; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $device_no = $self->card->device_no; + my $ss7_subinterface = $self->ss7_subinterface; + my $ss7_tdmchan = $self->ss7_tdmchan; + my $hwec_mode = $self->card->hwec_mode; + my $ss7_tdminterface = $self->ss7_tdminterface; + my $wanpipe_ss7_interfaces_template = $self->card->current_dir."/templates/ss7_a10u/wanpipe.ss7.$ss7_subinterface"; + + open(FH, $wanpipe_ss7_interfaces_template) or die "Can't open $wanpipe_ss7_interfaces_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + + open(FH, ">>$wanpipe_ss7_conf_file") or die "Cant open $wanpipe_ss7_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + $wp_file =~ s/SS7SIGCHAN/$ss7_sigchan/g; + $wp_file =~ s/TDMVOICECHAN/$ss7_tdmchan/g; + $wp_file =~ s/VOICEINTERFACE/$ss7_tdminterface/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + + + print FH $wp_file; + close (FH); +} + +sub gen_wanpipe_conf{ + my ($self) = @_; + my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm.a10u"; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $device_no = $self->card->device_no; + my $pci_slot = $self->card->pci_slot; + my $pci_bus = $self->card->pci_bus; + my $fe_media = $self->fe_media; + my $fe_lcode = $self->fe_lcode; + my $fe_frame = $self->fe_frame; + my $fe_line = $self->fe_line; + my $te_sig_mode = $self->te_sig_mode; + my $fe_clock = $self->fe_clock; + my $ss7_option = $self->ss7_option; + my $dchan = 0; + my $fe_lbo; + my $fe_cpu; + + my $te_sig_mode_line=''; + + + if ($ss7_option == 1){ + $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a10u/wanpipe.ss7.4"; + } elsif ($ss7_option == 2){ + $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u"; + } + + if ($self->fe_line eq '1'){ + $fe_cpu='A'; + }elsif($self->fe_line eq '2'){ + $fe_cpu='B'; + }else{ + print "Error: Invalid port on A101-2u\n"; + exit 1; + } + + if ($self->fe_media eq 'T1'){ + if ($self->signalling eq 'PRI CPE' | $self->signalling eq 'PRI NET'){ + $te_sig_mode = ''; + $dchan = 24; + } + $fe_lbo='0DB'; + }else{ + if ($self->signalling eq 'PRI CPE' | $self->signalling eq 'PRI NET'){ + $dchan = 16; + } + $fe_lbo='120OH'; + } + + + if ($te_sig_mode eq ''){ + $te_sig_mode_line=''; + }else{ + $te_sig_mode_line= 'TE_SIG_MODE = '.$te_sig_mode; + } + + + open(FH, $wanpipe_conf_template ) or die "Cannot open $wanpipe_conf_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + open(FH, ">>$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + $wp_file =~ s/SLOTNUM/$pci_slot/g; + $wp_file =~ s/BUSNUM/$pci_bus/g; + $wp_file =~ s/FEMEDIA/$fe_media/g; + $wp_file =~ s/FELCODE/$fe_lcode/g; + $wp_file =~ s/TESIGMODE/$te_sig_mode_line/g; + $wp_file =~ s/FEFRAME/$fe_frame/g; + $wp_file =~ s/FECPU/$fe_cpu/g; + $wp_file =~ s/FECLOCK/$fe_clock/g; + $wp_file =~ s/FELBO/$fe_lbo/g; + $wp_file =~ s/TDMVDCHAN/$dchan/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + + print FH $wp_file; + close (FH); + +# print "\n created $fname for A$card_model $devnum SLOT $slot BUS $bus HWEC $hwec_mode\n"; +} +sub gen_zaptel_conf{ + my ($self, $dchan_str) = @_; + my $zap_lcode; + my $zap_frame; + my $zap_crc4; + + if ( $self->fe_lcode eq 'B8ZS' ){ + $zap_lcode='b8zs'; + } elsif ( $self->fe_lcode eq 'AMI' ){ + $zap_lcode='ami'; + } elsif ( $self->fe_lcode eq 'HDB3' ){ + $zap_lcode='hdb3'; + } else { + printf("Error: invalid line coding %s\n", $self->fe_lcode); + exit; + } + + if ( $self->fe_frame eq 'ESF' ){ + $zap_frame='esf'; + } elsif ( $self->fe_frame eq 'D4' ){ + $zap_frame='d4'; + } elsif ( $self->fe_frame eq 'CRC4' ){ + $zap_frame='ccs'; + $zap_crc4=',crc4'; + } elsif ( $self->fe_frame eq 'NCRC4' ){ + $zap_frame='ccs'; + } else { + printf("Error: invalid line framing %s\n", $self->fe_frame); + exit; + } + + my $zp_file=''; + + $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + + + # $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span: ".$self->card->span_no."]\n"; + $zp_file.="span=".$self->card->tdmv_span_no.",0,0,".$zap_frame.",".$zap_lcode.$zap_crc4."\n"; + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + if ( $self->fe_media eq 'T1' ){ + $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; + } else { + $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; + } + } else { + my $zap_signal; + if ( $self->signalling eq 'E & M' | $self->signalling eq 'E & M Wink' ){ + $zap_signal='e&m'; + } elsif ( $self->signalling eq 'FXS - Loop Start' ){ + $zap_signal='fxsls'; + } elsif ( $self->signalling eq 'FXS - Ground Start' ){ + $zap_signal='fxsgs'; + } elsif ( $self->signalling eq 'FXS - Kewl Start' ){ + $zap_signal='fxsks'; + } elsif ( $self->signalling eq 'FX0 - Loop Start' ){ + $zap_signal='fxols'; + } elsif ( $self->signalling eq 'FX0 - Ground Start' ){ + $zap_signal='fxogs'; + } elsif ( $self->signalling eq 'FX0 - Kewl Start' ){ + $zap_signal='fxoks'; + } else { + printf("Error: invalid signalling %s\n", $self->card->signalling); + } + + if ( $self->fe_media eq 'T1' ){ + $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + } else { + $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } + } + return $zp_file; + +} + +sub gen_zapata_conf{ + my ($self) = @_; + + my $zp_file=''; + + $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + +# $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span: ".$self->card->span_no."]\n"; + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + $zp_file.="switchtype=".$self->pri_switchtype."\n"; + } + + $zp_file.="context=".$self->card->zap_context."\n"; + $zp_file.="group=".$self->card->zap_group."\n"; + + if ( $self->signalling eq 'PRI NET' ){ + $zp_file.="signalling=pri_net\n"; + } elsif ( $self->signalling eq 'PRI CPE' ){ + $zp_file.="signalling=pri_cpe\n"; + } elsif ( $self->signalling eq 'E & M' ){ + $zp_file.="signalling=em\n"; + } elsif ($self->signalling eq 'E & M Wink' ){ + $zp_file.="signalling=em_w\n"; + } elsif ( $self->signalling eq 'FXS - Loop Start' ){ + $zp_file.="signalling=fxs_ls\n"; + } elsif ( $self->signalling eq 'FXS - Ground Start' ){ + $zp_file.="signalling=fxs_gs\n"; + } elsif ( $self->signalling eq 'FXS - Kewl Start' ){ + $zp_file.="signalling=fxs_ks\n"; + } elsif ( $self->signalling eq 'FX0 - Loop Start' ){ + $zp_file.="signalling=fxo_ls\n"; + } elsif ( $self->signalling eq 'FX0 - Ground Start' ){ + $zp_file.="signalling=fxo_gs\n"; + } elsif ( $self->signalling eq 'FX0 - Kewl Start' ){ + $zp_file.="signalling=fxo_ks\n"; + } else { + printf("Error: invalid signalling %s\n", $self->signalling); + } + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + if ( $self->fe_media eq 'T1' ){ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + }else{ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + } + } else { + if ( $self->fe_media eq 'T1' ){ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + }else{ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } + + } + return $zp_file; + +} + +1; diff --git a/util/tmp_davidy/wancfg_zaptel/A10x.pm b/util/tmp_davidy/wancfg_zaptel/A10x.pm new file mode 100644 index 0000000..2172c3f --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/A10x.pm @@ -0,0 +1,429 @@ +#class A10x +#for A10x-sh series cards + +package A10x; +use Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _current_dir => undef, + _card => undef, + _fe_line => undef, + _fe_media => 'T1', + _fe_lcode => 'B8ZS', + _fe_frame => 'ESF', + _fe_clock => 'NORMAL', + _te_sig_mode => undef, + _te_ref_clock => '0', + _signalling => 'PRI_CPE', + _pri_switchtype => 'national', + _hw_dchan => '0', + _ss7_sigchan => undef, + _ss7_option => undef, + _ss7_tdmchan => undef, + _ss7_subinterface => undef, + _ss7_tdminterface => undef, + }; + bless $self, $class; + return $self; +} + +sub card { + my ( $self, $card ) = @_; + $self->{_card} = $card if defined($card); + return $self->{_card}; +} +sub fe_line { + my ( $self, $fe_line ) = @_; + $self->{_fe_line} = $fe_line if defined($fe_line); + return $self->{_fe_line}; +} + +sub te_ref_clock { + my ( $self, $te_ref_clock ) = @_; + $self->{_te_ref_clock} = $te_ref_clock if defined($te_ref_clock); + return $self->{_te_ref_clock}; +} +sub signalling { + my ( $self, $signalling ) = @_; + $self->{_signalling} = $signalling if defined($signalling); + return $self->{_signalling}; +} + +sub fe_media { + my ( $self, $fe_media ) = @_; + $self->{_fe_media} = $fe_media if defined($fe_media); + return $self->{_fe_media}; +} + +sub fe_lcode { + my ( $self, $fe_lcode) = @_; + $self->{_fe_lcode} = $fe_lcode if defined($fe_lcode); + return $self->{_fe_lcode}; +} + +sub fe_frame { + my ( $self, $fe_frame ) = @_; + $self->{_fe_frame} = $fe_frame if defined($fe_frame); + return $self->{_fe_frame}; +} + +sub hw_dchan { + my ( $self, $hw_dchan ) = @_; + $self->{_hw_dchan} = $hw_dchan if defined($hw_dchan); + return $self->{_hw_dchan}; +} + +sub fe_clock { + my ( $self, $fe_clock ) = @_; + $self->{_fe_clock} = $fe_clock if defined($fe_clock); + return $self->{_fe_clock}; +} + +sub te_sig_mode { + my ( $self, $te_sig_mode ) = @_; + $self->{_te_sig_mode} = $te_sig_mode if defined($te_sig_mode); + return $self->{_te_sig_mode}; +} + +sub pri_switchtype { + my ( $self, $pri_switchtype ) = @_; + $self->{_pri_switchtype} = $pri_switchtype if defined($pri_switchtype); + return $self->{_pri_switchtype}; +} + +sub current_dir { + my ( $self, $current_dir ) = @_; + $self->{_current_dir} = $current_dir if defined($current_dir); + return $self->{_current_dir}; +} + +sub ss7_option { + my ( $self, $ss7_option ) = @_; + $self->{_ss7_option} = $ss7_option if defined($ss7_option); + return $self->{_ss7_option}; +} + +sub ss7_sigchan { + my ( $self, $ss7_sigchan ) = @_; + $self->{_ss7_sigchan} = $ss7_sigchan if defined($ss7_sigchan); + return $self->{_ss7_sigchan}; +} + +sub ss7_tdmchan { + my ( $self, $ss7_tdmchan ) = @_; + $self->{_ss7_tdmchan} = $ss7_tdmchan if defined($ss7_tdmchan); + return $self->{_ss7_tdmchan}; +} + +sub ss7_subinterface { + my ( $self, $ss7_subinterface ) = @_; + $self->{_ss7_subinterface} = $ss7_subinterface if defined($ss7_subinterface); + return $self->{_ss7_subinterface}; +} + +sub ss7_tdminterface { + my ( $self, $ss7_tdminterface ) = @_; + $self->{_ss7_tdminterface} = $ss7_tdminterface if defined($ss7_tdminterface); + return $self->{_ss7_tdminterface}; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $i; + my $valid = 0; + for $i (0..$#list) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $#list+1) { + print "Invalid option: Value out of range \n"; + } else { + return $1-1 ; + } + } else { + print "Invalid option: Input an integer\n"; + } + } +} + +sub print { + my ($self) = @_; + $self->card->print(); + printf (" fe_line: %s\n fe_media: %s\n fe_lcode: %s\n fe_frame: %s \n fe_clock:%s\n ", $self->fe_line, $self->fe_media, $self->fe_lcode, $self->fe_frame, $self->fe_clock); + +} + +sub gen_wanpipe_ss7_subinterfaces{ + my ($self) = @_; + my $wanpipe_ss7_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + my $ss7_sigchan = $self->ss7_sigchan; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $device_no = $self->card->device_no; + my $ss7_subinterface = $self->ss7_subinterface; + my $ss7_tdmchan = $self->ss7_tdmchan; + my $hwec_mode = $self->card->hwec_mode; + my $ss7_tdminterface = $self->ss7_tdminterface; + my $wanpipe_ss7_interfaces_template = $self->card->current_dir."/templates/ss7_a100/wanpipe.ss7.$ss7_subinterface"; + + open(FH, $wanpipe_ss7_interfaces_template) or die "Can't open $wanpipe_ss7_interfaces_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + + open(FH, ">>$wanpipe_ss7_conf_file") or die "Cant open $wanpipe_ss7_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + $wp_file =~ s/SS7SIGCHAN/$ss7_sigchan/g; + $wp_file =~ s/TDMVOICECHAN/$ss7_tdmchan/g; + $wp_file =~ s/HWECMODE/$hwec_mode/g; + $wp_file =~ s/VOICEINTERFACE/$ss7_tdminterface/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + + print FH $wp_file; + close (FH); +} + +sub gen_wanpipe_conf{ + my ($self) = @_; + my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm.a100"; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + my $device_no = $self->card->device_no; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $pci_slot = $self->card->pci_slot; + my $pci_bus = $self->card->pci_bus; + my $fe_media = $self->fe_media; + my $fe_lcode = $self->fe_lcode; + my $fe_frame = $self->fe_frame; + my $fe_line = $self->fe_line; + my $fe_clock = $self->fe_clock; + my $te_ref_clock = $self->te_ref_clock; + my $te_sig_mode = $self->te_sig_mode; + my $hwec_mode = $self->card->hwec_mode; + my $hw_dtmf = $self->card->hw_dtmf; + my $ss7_option = $self->ss7_option; + my $dchan = $self->hw_dchan; + my $fe_lbo; + + my $te_sig_mode_line=''; + + if ($ss7_option == 1){ + $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a100/wanpipe.ss7.4"; + } elsif ($ss7_option == 2){ + $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a100/wanpipe.tdmvoiceapi.a100"; + } + + if($self->signalling eq 'TDM API'){ + $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm_api.a100"; + } + + if ($self->fe_media eq 'T1'){ + if ($self->signalling eq 'PRI CPE' | $self->signalling eq 'PRI NET' | $self->signalling eq 'SS7 - Sangoma Signal Media Gateway'){ + $te_sig_mode = ''; + $dchan = 24; + } + $fe_lbo='0DB'; + }else{ + if ($self->signalling eq 'PRI CPE' | $self->signalling eq 'PRI NET' | $self->signalling eq 'SS7 - Sangoma Signal Media Gateway'){ + $dchan = 16; + # $te_sig_mode = 'TE_SIG_MODE = CCS'; + }else { + # $te_sig_mode = 'TE_SIG_MODE = CAS'; + } + $fe_lbo='120OH'; + } + + if ($te_sig_mode eq ''| $self->fe_media eq 'T1'){ + $te_sig_mode_line=''; + }else{ + $te_sig_mode_line= 'TE_SIG_MODE = '.$te_sig_mode; + } + + open(FH, $wanpipe_conf_template) or die "Can't open $wanpipe_conf_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + + open(FH, ">>$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + $wp_file =~ s/SLOTNUM/$pci_slot/g; + $wp_file =~ s/BUSNUM/$pci_bus/g; + $wp_file =~ s/FEMEDIA/$fe_media/g; + $wp_file =~ s/FELCODE/$fe_lcode/g; + $wp_file =~ s/FEFRAME/$fe_frame/g; + $wp_file =~ s/FELINE/$fe_line/g; + $wp_file =~ s/TESIGMODE/$te_sig_mode_line/g; + $wp_file =~ s/FECLOCK/$fe_clock/g; + $wp_file =~ s/TEREFCLOCK/$te_ref_clock/g; + $wp_file =~ s/FELBO/$fe_lbo/g; + $wp_file =~ s/TDMVDCHAN/$dchan/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + $wp_file =~ s/HWECMODE/$hwec_mode/g; + $wp_file =~ s/HWDTMF/$hw_dtmf/g; + + print FH $wp_file; + close (FH); + +# print "\n created $fname for A$card_model $devnum SLOT $slot BUS $bus HWEC $hwec_mode\n"; +} + + +sub gen_zaptel_conf{ + my ($self, $dchan_str) = @_; + my $zap_lcode; + my $zap_frame; + my $zap_crc4; + my $zp_file=""; + + if ( $self->fe_lcode eq 'B8ZS' ){ + $zap_lcode='b8zs'; + } elsif ( $self->fe_lcode eq 'AMI' ){ + $zap_lcode='ami'; + } elsif ( $self->fe_lcode eq 'HDB3' ){ + $zap_lcode='hdb3'; + } else { + printf("Error: invalid line coding %s\n", $self->fe_lcode); + exit; + } + + if ( $self->fe_frame eq 'ESF' ){ + $zap_frame='esf'; + } elsif ( $self->fe_frame eq 'D4' ){ + $zap_frame='d4'; + } elsif ( $self->fe_frame eq 'CRC4' ){ + $zap_frame='ccs'; + $zap_crc4=',crc4'; + } elsif ( $self->fe_frame eq 'NCRC4' ){ + $zap_frame='ccs'; + } else { + printf("Error: invalid line framing %s\n", $self->fe_frame); + exit; + } + + + $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + $zp_file.="span=".$self->card->tdmv_span_no.",0,0,".$zap_frame.",".$zap_lcode.$zap_crc4."\n"; + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + if ( $self->fe_media eq 'T1' ){ + $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; + } else { + $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; + } + } else { + my $zap_signal; + if ( $self->signalling eq 'E & M' | $self->signalling eq 'E & M Wink' ){ + $zap_signal='e&m'; + } elsif ( $self->signalling eq 'FXS - Loop Start' ){ + $zap_signal='fxsls'; + } elsif ( $self->signalling eq 'FXS - Ground Start' ){ + $zap_signal='fxsgs'; + } elsif ( $self->signalling eq 'FXS - Kewl Start' ){ + $zap_signal='fxsks'; + } elsif ( $self->signalling eq 'FX0 - Loop Start' ){ + $zap_signal='fxols'; + } elsif ( $self->signalling eq 'FX0 - Ground Start' ){ + $zap_signal='fxogs'; + } elsif ( $self->signalling eq 'FX0 - Kewl Start' ){ + $zap_signal='fxoks'; + } else { + printf("Error: invalid signalling %s\n", $self->card->signalling); + } + + if ( $self->fe_media eq 'T1' ){ + $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + } else { + $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } + } + return $zp_file; + +} + +sub gen_zapata_conf{ + my ($self) = @_; + + my $zp_file=''; + $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + + #$zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span: ".$self->card->span_no."]\n"; + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + $zp_file.="switchtype=".$self->pri_switchtype."\n"; + } + + $zp_file.="context=".$self->card->zap_context."\n"; + $zp_file.="group=".$self->card->zap_group."\n"; + + if ( $self->signalling eq 'PRI NET' ){ + $zp_file.="signalling=pri_net\n"; + } elsif ( $self->signalling eq 'PRI CPE' ){ + $zp_file.="signalling=pri_cpe\n"; + } elsif ( $self->signalling eq 'E & M' ){ + $zp_file.="signalling=em\n"; + } elsif ($self->signalling eq 'E & M Wink' ){ + $zp_file.="signalling=em_w\n"; + } elsif ( $self->signalling eq 'FXS - Loop Start' ){ + $zp_file.="signalling=fxs_ls\n"; + } elsif ( $self->signalling eq 'FXS - Ground Start' ){ + $zp_file.="signalling=fxs_gs\n"; + } elsif ( $self->signalling eq 'FXS - Kewl Start' ){ + $zp_file.="signalling=fxs_ks\n"; + } elsif ( $self->signalling eq 'FX0 - Loop Start' ){ + $zp_file.="signalling=fxo_ls\n"; + } elsif ( $self->signalling eq 'FX0 - Ground Start' ){ + $zp_file.="signalling=fxo_gs\n"; + } elsif ( $self->signalling eq 'FX0 - Kewl Start' ){ + $zp_file.="signalling=fxo_ks\n"; + } else { + printf("Error: invalid signalling %s\n", $self->signalling); + } + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + if ( $self->fe_media eq 'T1' ){ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + }else{ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + } + } else { + if ( $self->fe_media eq 'T1' ){ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + }else{ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } + + } + return $zp_file; + +} + +1; diff --git a/util/tmp_davidy/wancfg_zaptel/A20x.pm b/util/tmp_davidy/wancfg_zaptel/A20x.pm new file mode 100644 index 0000000..3870296 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/A20x.pm @@ -0,0 +1,164 @@ +#class A20x +#for A200 series cards + +package A20x; +use Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _card => undef, + _tdm_opermode => 'FCC', + _tdm_law => 'MULAW', + _rm_network_sync => 'NO', + _analog_modules => undef, + }; + bless $self, $class; + return $self; +} + +sub card { + my ( $self, $card ) = @_; + $self->{_card} = $card if defined($card); + return $self->{_card}; +} + +sub tdm_opermode { + my ( $self, $tdm_opermode ) = @_; + $self->{_tdm_opermode} = $tdm_opermode if defined($tdm_opermode); + return $self->{_tdm_opermode}; +} + +sub tdm_law { + my ( $self, $tdm_law ) = @_; + $self->{_tdm_law} = $tdm_law if defined($tdm_law); + return $self->{_tdm_law}; +} + +sub rm_network_sync { + my ( $self, $rm_network_sync ) = @_; + $self->{_rm_network_sync} = $rm_network_sync if defined($rm_network_sync); + return $self->{_rm_network_sync}; +} + +sub analog_modules { + my ( $self, $analog_modules ) = @_; + $self->{_analog_modules} = $analog_modules if defined($analog_modules); + return $self->{_analog_modules}; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $i; + my $valid = 0; + for $i (0..$#list) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $#list+1) { + print "Invalid option: Value out of range \n"; + } else { + return $1-1 ; + } + } else { + print "Invalid option: Input an integer\n"; + } + } +} + +sub print { + my ($self) = @_; + $self->card->print(); + +} + +sub gen_wanpipe_conf{ + my ($self) = @_; + my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm.a200"; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + + my $device_no = $self->card->device_no; + my $tdmv_span_no = $self->card->tdmv_span_no; + + my $pci_slot = $self->card->pci_slot; + my $pci_bus = $self->card->pci_bus; + my $tdm_law = $self->tdm_law; + my $tdm_opermode = $self->tdm_opermode; + my $rm_network_sync = $self->rm_network_sync; + my $hwec_mode = $self->card->hwec_mode; + my $hw_dtmf = $self->card->hw_dtmf; + + + open(FH, $wanpipe_conf_template) or die "Can open $wanpipe_conf_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + open(FH, ">$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + $wp_file =~ s/SLOTNUM/$pci_slot/g; + $wp_file =~ s/BUSNUM/$pci_bus/g; + $wp_file =~ s/TDM_LAW/$tdm_law/g; + $wp_file =~ s/RMNETSYNC/$rm_network_sync/g; + $wp_file =~ s/TDM_OPERMODE/$tdm_opermode/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + $wp_file =~ s/HWECMODE/$hwec_mode/g; + $wp_file =~ s/HWDTMF/$hw_dtmf/g; + + print FH $wp_file; + close (FH); + +# print "\n created $fname for A$card_model $devnum SLOT $slot BUS $bus HWEC $hwec_mode\n"; +} +sub gen_zaptel_conf{ + my ($self, $channel, $type) = @_; + my $zp_file=''; + if ( $type eq 'fxo'){ + #this is an FXS module + $zp_file.="fxoks=$channel\n"; + }else{ + $zp_file.="fxsks=$channel\n"; + } + return $zp_file; +} +sub gen_zapata_conf{ + my ($self, $channel, $type) = @_; + my $zp_file=''; + $zp_file.="context=".$self->card->zap_context."\n"; + $zp_file.="group=".$self->card->zap_group."\n"; + + if ( $type eq 'fxo'){ + #this is an FXS module + $zp_file.="signalling = fxo_ks\n"; + }else{ + $zp_file.="signalling = fxs_ks\n"; + } + $zp_file.="channel => $channel\n\n"; + return $zp_file; +} + +1; diff --git a/util/tmp_davidy/wancfg_zaptel/A50x.pm b/util/tmp_davidy/wancfg_zaptel/A50x.pm new file mode 100644 index 0000000..b9bb939 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/A50x.pm @@ -0,0 +1,163 @@ +#class A50x +#for A50x-sh series cards + +package A50x; +use Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _current_dir => undef, + _card => undef, + _fe_line => undef, + _fe_media => 'BRI', + _bri_switchtype => 'etsi', + _bri_country => 'europe' + }; + bless $self, $class; + return $self; +} + +sub card { + my ( $self, $card ) = @_; + $self->{_card} = $card if defined($card); + return $self->{_card}; +} + +sub fe_line { + my ( $self, $fe_line ) = @_; + $self->{_fe_line} = $fe_line if defined($fe_line); + return $self->{_fe_line}; +} + +sub fe_media { + my ( $self, $fe_media ) = @_; + $self->{_fe_media} = $fe_media if defined($fe_media); + return $self->{_fe_media}; +} + +sub bri_switchtype { + my ( $self, $bri_switchtype ) = @_; + $self->{_bri_switchtype} = $bri_switchtype if defined($bri_switchtype); + return $self->{_bri_switchtype}; +} + +sub current_dir { + my ( $self, $current_dir ) = @_; + $self->{_current_dir} = $current_dir if defined($current_dir); + return $self->{_current_dir}; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $i; + my $valid = 0; + for $i (0..$#list) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $#list+1) { + print "Invalid option: Value out of range \n"; + } else { + return $1-1 ; + } + } else { + print "Invalid option: Input an integer\n"; + } + } +} + +sub gen_wanpipe_conf{ + my ($self) = @_; + my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm_api.a500"; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + + my $device_no = $self->card->device_no; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $pci_slot = $self->card->pci_slot; + my $pci_bus = $self->card->pci_bus; + my $fe_media = $self->fe_media; + my $fe_line = $self->fe_line; + my $hwec_mode = $self->card->hwec_mode; + + + open(FH, $wanpipe_conf_template) or die "Can't open $wanpipe_conf_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + + open(FH, ">>$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + $wp_file =~ s/SLOTNUM/$pci_slot/g; + $wp_file =~ s/BUSNUM/$pci_bus/g; + $wp_file =~ s/FEMEDIA/$fe_media/g; + $wp_file =~ s/FELINE/$fe_line/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + $wp_file =~ s/HWECMODE/$hwec_mode/g; + + print FH $wp_file; + close (FH); + +} + + +sub gen_bri_conf{ + my ($self, $span, $type, $group, $country, $operator, $conn_type) = @_; + my $bri_file=''; + + $bri_file.="\n"; + $bri_file.="group=$group\n"; + $bri_file.="country=$country\n"; + $bri_file.="operator=$operator\n"; + $bri_file.="connection_type=$conn_type\n"; + + + if ( $type eq 'bri_nt'){ + $bri_file.="signalling=bri_nt\n"; + }else{ + $bri_file.="signalling=bri_te\n"; + } + + $bri_file.="spans=$span\n"; + + return $bri_file; +} + + +sub gen_woomera_conf{ + my ($self, $group, $context) = @_; + my $woomera_file=''; + + $woomera_file.="\n"; + $woomera_file.="context=$context\n"; + $woomera_file.="group=$group\n"; + return $woomera_file; +} + + +1; diff --git a/util/tmp_davidy/wancfg_zaptel/Card.pm b/util/tmp_davidy/wancfg_zaptel/Card.pm new file mode 100644 index 0000000..7203bed --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/Card.pm @@ -0,0 +1,117 @@ +package Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _current_dir => undef, + _cfg_dir => undef, + _device_no => undef, + _tdmv_span_no => undef, + _card_model => undef, + _pci_slot => undef, + _pci_bus => undef, + _fe_cpu => 'A', + _hwec_mode => 'NO', + _hw_dtmf => 'NO', + _first_chan => '0', + _zap_context => undef, + _zap_group => undef + }; + bless $self, $class; + return $self; +} + +sub device_no { + my ( $self, $device_no ) = @_; + $self->{_device_no} = $device_no if defined($device_no); + return $self->{_device_no}; +} + +sub tdmv_span_no { + my ( $self, $tdmv_span_no ) = @_; + $self->{_tdmv_span_no} = $tdmv_span_no if defined($tdmv_span_no); + return $self->{_tdmv_span_no}; +} + +sub card_model { + my ( $self, $card_model ) = @_; + $self->{_card_model} = $card_model if defined($card_model); + return $self->{_card_model}; +} + +sub pci_slot { + my ( $self, $pci_slot ) = @_; + $self->{_pci_slot} = $pci_slot if defined($pci_slot); + return $self->{_pci_slot}; +} + +sub pci_bus { + my ( $self, $pci_bus ) = @_; + $self->{_pci_bus} = $pci_bus if defined($pci_bus); + return $self->{_pci_bus}; +} + +sub fe_cpu { + my ( $self, $fe_cpu ) = @_; + $self->{_fe_cpu } = $fe_cpu if defined($fe_cpu); + return $self->{_fe_cpu}; +} + +sub hwec_mode { + my ( $self, $hwec_mode ) = @_; + $self->{_hwec_mode} = $hwec_mode if defined($hwec_mode); + return $self->{_hwec_mode}; +} + +sub hw_dtmf { + my ( $self, $hw_dtmf ) = @_; + $self->{_hw_dtmf} = $hw_dtmf if defined($hw_dtmf); + return $self->{_hw_dtmf}; +} + +sub signalling { + my ( $self, $signalling ) = @_; + $self->{_signalling} = $signalling if defined($signalling); + return $self->{_signalling}; +} + +sub first_chan { + my ( $self, $first_chan ) = @_; + $self->{_first_chan} = $first_chan if defined($first_chan); + return $self->{_first_chan}; +} + +sub zap_context { + my ( $self, $zap_context ) = @_; + $self->{_zap_context} = $zap_context if defined($zap_context); + return $self->{_zap_context}; +} + +sub zap_group { + my ( $self, $zap_group ) = @_; + $self->{_zap_group} = $zap_group if defined($zap_group); + return $self->{_zap_group}; +} + +sub current_dir { + my ( $self, $current_dir ) = @_; + $self->{_current_dir} = $current_dir if defined($current_dir); + return $self->{_current_dir}; +} + +sub cfg_dir { + my ( $self, $cfg_dir ) = @_; + $self->{_cfg_dir} = $cfg_dir if defined($cfg_dir); + return $self->{_cfg_dir}; +} + +sub print { + my ($self) = @_; + printf (" span_no: %s\n card_model: %s\n pci_slot: %s\n pci_bus: %s\n hwec_mode: %s\n signalling %s\n first_chan: %s\n", $self->span_no, $self->card_model, $self->pci_slot, $self->pci_bus, $self->hwec_mode, $self->signalling, $self->first_chan); + +} + + +1; diff --git a/util/tmp_davidy/wancfg_zaptel/Makefile b/util/tmp_davidy/wancfg_zaptel/Makefile new file mode 100644 index 0000000..50e5b7c --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/Makefile @@ -0,0 +1,25 @@ +# ============================================================================ +# Makefile Make script for building Linux WAN router utilities. +# ---------------------------------------------------------------------------- +# Copyright (c) 1995-2000 Sangoma Technologies Inc. All Rights Reserved. +# ============================================================================ + +####### MACROS ############################################################### + +# Build options. +WZDIR=/etc/wanpipe/wancfg_zaptel +WAN_VIRTUAL= + +all: + +install: + @echo "Installing Wanconfig Zaptel/SMG utilites in $(WAN_VIRTUAL)/$(WZDIR)" + $(shell ./install.sh $(WZDIR) $(WAN_VIRTUAL) ) + +uninstall: + @echo "Un-installing Wanpipe utilites from $(WAN_VIRTUAL)/$(WZDIR)" + $(shell ./uninstall.sh $(WZDIR) $(WAN_VIRTUAL) ) + +clean: + @echo "Removing temporary wancfg_zaptel files" + $(shell ./clean.sh) diff --git a/util/tmp_davidy/wancfg_zaptel/clean.sh b/util/tmp_davidy/wancfg_zaptel/clean.sh new file mode 100755 index 0000000..5b8315d --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/clean.sh @@ -0,0 +1,4 @@ +#!/bin/sh + + +rm -f tmp_cfg/* diff --git a/util/tmp_davidy/wancfg_zaptel/install.sh b/util/tmp_davidy/wancfg_zaptel/install.sh new file mode 100755 index 0000000..8bcbe66 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/install.sh @@ -0,0 +1,29 @@ +#!/bin/sh + + +WAN_VIRTUAL=$2 +WZDIR=${1:-usr/local/sbin/wancfg_zaptel} + +if [ -z $WZDIR ]; then + echo "Directory not found $WZDIR" + exit 1 +fi + +if [ -e $WAN_VIRTUAL/$WZDIR ]; then + rm -rf $WAN_VIRTUAL/$WZDIR +fi + +mkdir -p $WAN_VIRTUAL/$WZDIR +cp -rf . $WAN_VIRTUAL/$WZDIR + +cp -rf setup-sangoma $WAN_VIRTUAL/usr/local/sbin +chmod 755 $WAN_VIRTUAL/usr/local/sbin/setup-sangoma + +cp -rf wancfg_zaptel $WAN_VIRTUAL/usr/sbin +chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_zaptel + +cp -rf wancfg_smg $WAN_VIRTUAL/usr/sbin +chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_smg + +cp -rf wancfg_tdmapi $WAN_VIRTUAL/usr/sbin +chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_tdmapi diff --git a/util/tmp_davidy/wancfg_zaptel/setup-sangoma b/util/tmp_davidy/wancfg_zaptel/setup-sangoma new file mode 100755 index 0000000..1690edd --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/setup-sangoma @@ -0,0 +1,5 @@ +#!/bin/sh +home=`pwd` +cd /etc/wanpipe/wancfg_zaptel +./wancfg_zaptel.pl --trixbox +cd $home diff --git a/util/tmp_davidy/wancfg_zaptel/templates/smg_bri.conf b/util/tmp_davidy/wancfg_zaptel/templates/smg_bri.conf new file mode 100644 index 0000000..6223e1b --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/smg_bri.conf @@ -0,0 +1,12 @@ +;Possible values for country codes (default:europe) +; australia, austria, belgium, canada, chile, denmark, europe, finland, france, +; germany, hong_kong, india, irlande, israel, italy, japan, korea, luxembourg, +; netherlands, new_zealand, norway, portugal, singapore, south_africa, spain, +; sweden, switzerland, taiwan, uk, usa, ussr + +;verbose levels (1-10) +verbose=5 + +;protocol capture (yes or no) +;output will be sent to /var/log/sangoma_bri +prot_capture=yes diff --git a/util/tmp_davidy/wancfg_zaptel/templates/smgbri_start_script b/util/tmp_davidy/wancfg_zaptel/templates/smgbri_start_script new file mode 100644 index 0000000..1fab1fe --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/smgbri_start_script @@ -0,0 +1,24 @@ +#!/bin/sh +cnt=0 +max_delay=30 +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/wptdm_s1c1 ]; then + break; + fi + + echo "Waiting for TDM API device /dev/wp_tdm ($i/$max_delay)..." + sleep 2 +done + +if [ ! -e /dev/wptdm_s1c1 ]; then + echo + echo "Error: Sangoma TDM API device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +smg_ctrl start diff --git a/util/tmp_davidy/wancfg_zaptel/templates/smgbri_start_script_addon b/util/tmp_davidy/wancfg_zaptel/templates/smgbri_start_script_addon new file mode 100644 index 0000000..ad57d2b --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/smgbri_start_script_addon @@ -0,0 +1,24 @@ + +cnt=0 +max_delay=30 +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/wptdm_s1c1 ]; then + break; + fi + + echo "Waiting for TDM API device /dev/wp_tdm ($i/$max_delay)..." + sleep 2 +done + +if [ ! -e /dev/wptdm_s1c1 ]; then + echo + echo "Error: Sangoma TDM API device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +smg_ctrl start diff --git a/util/tmp_davidy/wancfg_zaptel/templates/smgbri_stop_script b/util/tmp_davidy/wancfg_zaptel/templates/smgbri_stop_script new file mode 100644 index 0000000..daed6de --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/smgbri_stop_script @@ -0,0 +1,2 @@ +#!/bin/sh +smg_ctrl stop diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.1 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.1 new file mode 100644 index 0000000..01adec1 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.1 @@ -0,0 +1,20 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Tue June 12 18:18:28 EST 2007 +# +# Note: This file was generated automatically +# by /usr/sbin/wancfg program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_TE1, Comment + +[interfaces] diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.2 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.2 new file mode 100644 index 0000000..7c9f79e --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.2 @@ -0,0 +1,2 @@ +wDEVNUMgVOICEINTERFACE = wanpipeDEVNUM, , TDM_VOICE_API, Comment + diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.3 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.3 new file mode 100644 index 0000000..73e45f8 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.3 @@ -0,0 +1,3 @@ +wDEVNUMgSS7SIGCHAN = wanpipeDEVNUM, , STACK, Comment +wDEVNUMgSS7SIGCHANxmtp2 = wanpipeDEVNUM, , API, lip_xmtp2, wDEVNUMgSS7SIGCHAN.xmtp2 + diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.4 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.4 new file mode 100644 index 0000000..c98b04e --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.4 @@ -0,0 +1,21 @@ +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = FELINE +TE_CLOCK = FECLOCK +TE_REF_CLOCK = TEREFCLOCK +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.5 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.5 new file mode 100644 index 0000000..e71c84e --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.5 @@ -0,0 +1,9 @@ +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = 0 + +[wDEVNUMgVOICEINTERFACE] +ACTIVE_CH = TDMVOICECHAN +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = 80 + diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.6 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.6 new file mode 100644 index 0000000..ee1e60d --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.6 @@ -0,0 +1,11 @@ + +[wDEVNUMgSS7SIGCHAN] +ACTIVE_CH = SS7SIGCHAN +MTU = 80 +MRU = 80 +TDMV_ECHO_OFF = NO +TDMV_HWEC = NO + +[wDEVNUMgSS7SIGCHANxmtp2] + +[wDEVNUMgSS7SIGCHAN.xmtp2] diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.tdmvoiceapi.a100 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.tdmvoiceapi.a100 new file mode 100644 index 0000000..52155c4 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.tdmvoiceapi.a100 @@ -0,0 +1,52 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Wed Dec 6 20:29:03 UTC 2006 +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_TE1, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE_API, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = FELINE +TE_CLOCK = FECLOCK +TE_REF_CLOCK = TEREFCLOCK +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = 0 +TDMV_HW_DTMF = HWDTMF + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = 80 diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.1 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.1 new file mode 100644 index 0000000..09bc65b --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.1 @@ -0,0 +1,20 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Tue June 12 18:18:28 EST 2006 +# +# Note: This file was generated automatically +# by /usr/sbin/wancfg program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT, Comment + +[interfaces] diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.2 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.2 new file mode 100644 index 0000000..7c9f79e --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.2 @@ -0,0 +1,2 @@ +wDEVNUMgVOICEINTERFACE = wanpipeDEVNUM, , TDM_VOICE_API, Comment + diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.3 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.3 new file mode 100644 index 0000000..73e45f8 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.3 @@ -0,0 +1,3 @@ +wDEVNUMgSS7SIGCHAN = wanpipeDEVNUM, , STACK, Comment +wDEVNUMgSS7SIGCHANxmtp2 = wanpipeDEVNUM, , API, lip_xmtp2, wDEVNUMgSS7SIGCHAN.xmtp2 + diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.4 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.4 new file mode 100644 index 0000000..6ee7b3b --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.4 @@ -0,0 +1,20 @@ +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = FECPU +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = 1 +TE_CLOCK = FECLOCK +TE_REF_CLOCK = 0 +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.5 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.5 new file mode 100644 index 0000000..1cf9c93 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.5 @@ -0,0 +1,9 @@ +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = 0 + +[wDEVNUMgVOICEINTERFACE] +ACTIVE_CH = TDMVOICECHAN +TDMV_ECHO_OFF = NO +TDMV_HWEC = NO +MTU = 80 + diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.6 b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.6 new file mode 100644 index 0000000..ee1e60d --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.6 @@ -0,0 +1,11 @@ + +[wDEVNUMgSS7SIGCHAN] +ACTIVE_CH = SS7SIGCHAN +MTU = 80 +MRU = 80 +TDMV_ECHO_OFF = NO +TDMV_HWEC = NO + +[wDEVNUMgSS7SIGCHANxmtp2] + +[wDEVNUMgSS7SIGCHAN.xmtp2] diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u new file mode 100644 index 0000000..379d36e --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u @@ -0,0 +1,50 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Wed Dec 6 20:29:03 UTC 2006 +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE_API, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = FECPU +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = 1 +TE_CLOCK = FECLOCK +TE_REF_CLOCK = 0 +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = 0 + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = NO +MTU = 80 diff --git a/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a100 b/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a100 new file mode 100644 index 0000000..878ab14 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a100 @@ -0,0 +1,51 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Wed Dec 6 20:29:03 UTC 2006 +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_TE1, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = FELINE +TE_CLOCK = FECLOCK +TE_REF_CLOCK = TEREFCLOCK +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = TDMVDCHAN +TDMV_HW_DTMF = HWDTMF + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE diff --git a/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a10u b/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a10u new file mode 100644 index 0000000..cabfe8e --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a10u @@ -0,0 +1,50 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Tue Dec 12 16:21:45 UTC 2006 +# +# Note: This file was generated automatically +# by /usr/sbin/wancfg program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = FECPU +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = 1 +TE_CLOCK = FECLOCK +TE_REF_CLOCK = 0 +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = TDMVDCHAN + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = NO diff --git a/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a200 b/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a200 new file mode 100644 index 0000000..0f94c44 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a200 @@ -0,0 +1,44 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Mon Jul 31 17:10:23 EDT 2006 +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_ANALOG, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FXO/FXS +TDMV_LAW = TDM_LAW +TDMV_OPERMODE = TDM_OPERMODE +RM_NETWORK_SYNC = RMNETSYNC +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_HW_DTMF = HWDTMF + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE diff --git a/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm_api.a100 b/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm_api.a100 new file mode 100644 index 0000000..66c68ad --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm_api.a100 @@ -0,0 +1,52 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Date: Wed Dec 6 20:29:03 UTC 2006 +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + +[devices] +wanpipeDEVNUM = WAN_AFT_TE1, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE_API, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = FEMEDIA +FE_LCODE = FELCODE +FE_FRAME = FEFRAME +FE_LINE = FELINE +TE_CLOCK = FECLOCK +TE_REF_CLOCK = TEREFCLOCK +TESIGMODE +TE_HIGHIMPEDANCE = NO +LBO = FELBO +FE_TXTRISTATE = NO +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO +TDMV_DCHAN = TDMVDCHAN +TDMV_HW_DTMF = HWDTMF + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = 80 diff --git a/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm_api.a500 b/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm_api.a500 new file mode 100755 index 0000000..e61b711 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm_api.a500 @@ -0,0 +1,44 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + + + + +[devices] +wanpipeDEVNUM = WAN_AFT_ISDN_BRI, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE_API, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = BRI +FE_LINE = FELINE +TDMV_LAW = ALAW +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = 80 diff --git a/util/wancfg_zaptel/templates/rc.template b/util/tmp_davidy/wancfg_zaptel/templates/wanrouter.rc.template similarity index 100% rename from util/wancfg_zaptel/templates/rc.template rename to util/tmp_davidy/wancfg_zaptel/templates/wanrouter.rc.template diff --git a/util/tmp_davidy/wancfg_zaptel/templates/wanrouter.rc.template.FreeBSD b/util/tmp_davidy/wancfg_zaptel/templates/wanrouter.rc.template.FreeBSD new file mode 100644 index 0000000..a9f6188 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/wanrouter.rc.template.FreeBSD @@ -0,0 +1,34 @@ + +# /usr/local/etc/wanpipe/wanrouter.rc WAN router meta-configuration file. +# +# This file defines variables used by the router shell scripts +# and should be located in /usr/local/etc/wanpipe directory. These are: +# +# ROUTER_BOOT= Boot flag (YES/NO). +# WAN_CONF_DIR= Directory of wanpipe config files. +# WAN_INTR_DIR= Where to put wanpipe interface files. +# WAN_FIRMWARE_DIR= Where to put protocol firmware files. +# WAN_LOG= Where to put start-up log file. +# WAN_LOCK_DIR= Directory of wanpipe device lock files. +# WAN_DEVICES= Name of the wanpipe devices to be +# loaded on 'wanrouter start' +# (ex: "wanpipe1 wanpipe2 wanpipe3...") +# +# Note: Name of wanpipe devices correspond +# to the configuration files in +# /usr/local/etc/wanpipe directory: +# (ex. /usr/local/etc/wanpipe/wanpipe1.conf ) +# +# Note: This file is 'executed' by the shell script, so +# the usual shell syntax must be observed. +ROUTER_BOOT=YES +WAN_BIN_DIR=/usr/local/sbin +WAN_CONF_DIR=/usr/local/etc/wanpipe +WAN_INTR_DIR=/usr/local/etc/wanpipe/interfaces +WAN_MODULE_DIR=/usr/local/lib/wanpipe +WAN_FIRMWARE_DIR=/usr/local/etc/wanpipe/firmware +WAN_LOG=/var/log/wanrouter +WAN_LOCK_DIR=/var/lock +WAN_LIB_DIR=/usr/local/etc/wanpipe/lib +WAN_ADSL_LIST=/usr/local/etc/wanpipe/wan_adsl.list +WAN_DEVICES="WPSTARTUP" diff --git a/util/tmp_davidy/wancfg_zaptel/templates/woomera.conf b/util/tmp_davidy/wancfg_zaptel/templates/woomera.conf new file mode 100644 index 0000000..9fe5c8e --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/woomera.conf @@ -0,0 +1,12 @@ +[settings] +debug=2 + +[default] +host=localhost +port=42420 +audio_ip=127.0.0.1 +default_context=sangoma +debug=2 +dtmf_enable=1 +jb_enable=0 +progress_enable=0 diff --git a/util/tmp_davidy/wancfg_zaptel/templates/zapata-auto.conf b/util/tmp_davidy/wancfg_zaptel/templates/zapata-auto.conf new file mode 100644 index 0000000..ef0fd10 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/zapata-auto.conf @@ -0,0 +1,7 @@ +; Autogenerated by /usr/local/sbin/sangoma/setup-sangoma -- do not hand edit +; Zaptel Channels Configurations (zapata.conf) +; +; This is not intended to be a complete zapata.conf. Rather, it is intended +; to be #include-d by /etc/zapata.conf that will include the global settings +; +callerid=asreceived diff --git a/util/tmp_davidy/wancfg_zaptel/templates/zapata.conf b/util/tmp_davidy/wancfg_zaptel/templates/zapata.conf new file mode 100644 index 0000000..051f98f --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/zapata.conf @@ -0,0 +1,29 @@ +;autogenerated by /usr/local/sbin/config-zaptel do not hand edit +;Zaptel Channels Configurations (zapata.conf) +; +;For detailed zapata options, view /etc/asterisk/zapata.conf.orig + +[trunkgroups] + +[channels] +context=default +usecallerid=yes +hidecallerid=no +callwaiting=yes +usecallingpres=yes +callwaitingcallerid=yes +threewaycalling=yes +transfer=yes +canpark=yes +cancallforward=yes +callreturn=yes +echocancel=yes +echocancelwhenbridged=yes +relaxdtmf=yes +rxgain=0.0 +txgain=0.0 +group=1 +callgroup=1 +pickupgroup=1 + +immediate=no diff --git a/util/tmp_davidy/wancfg_zaptel/templates/zaptel.conf b/util/tmp_davidy/wancfg_zaptel/templates/zaptel.conf new file mode 100644 index 0000000..63741b7 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/zaptel.conf @@ -0,0 +1,5 @@ +# Autogenerated by /usr/local/sbin/sangoma/setup-sangoma -- do not hand edit +# Zaptel Channels Configurations (zaptel.conf) +# +loadzone=us +defaultzone=us diff --git a/util/tmp_davidy/wancfg_zaptel/templates/zaptel_cfg_script b/util/tmp_davidy/wancfg_zaptel/templates/zaptel_cfg_script new file mode 100644 index 0000000..9793904 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/zaptel_cfg_script @@ -0,0 +1,29 @@ +#!/bin/sh +#Make sure that udev/devfs zaptel device +#has come up. +cnt=0 +max_delay=30 + + +echo -n "Waiting for zaptel device /dev/zap ..." +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/zap ]; then + break; + fi + echo -n "." + sleep 2 +done +echo " " +if [ ! -e /dev/zap ]; then + echo + echo "Error: Zaptel device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +ztcfg -v + diff --git a/util/tmp_davidy/wancfg_zaptel/templates/zaptel_cfg_script.FreeBSD b/util/tmp_davidy/wancfg_zaptel/templates/zaptel_cfg_script.FreeBSD new file mode 100644 index 0000000..6f2deaf --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/templates/zaptel_cfg_script.FreeBSD @@ -0,0 +1,6 @@ +#!/bin/sh + +sleep 1 + +ztcfg -v + diff --git a/util/tmp_davidy/wancfg_zaptel/uninstall.sh b/util/tmp_davidy/wancfg_zaptel/uninstall.sh new file mode 100755 index 0000000..c8dd3c6 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/uninstall.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +WAN_VIRTUAL=$2 +WZDIR=${1:-usr/local/sbin/wancfg_zaptel} + +if [ -z $WZDIR ]; then + echo "Directory not found $WZDIR" + exit 1 +fi + +if [ -e $WAN_VIRTUAL/$WZDIR ]; then + rm -rf $WAN_VIRTUAL/$WZDIR +fi diff --git a/util/tmp_davidy/wancfg_zaptel/wancfg_smg b/util/tmp_davidy/wancfg_zaptel/wancfg_smg new file mode 100644 index 0000000..34d4049 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/wancfg_smg @@ -0,0 +1,45 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --smg --conf_dir=$WAN_BASE +cd $home diff --git a/util/tmp_davidy/wancfg_zaptel/wancfg_tdmapi b/util/tmp_davidy/wancfg_zaptel/wancfg_tdmapi new file mode 100755 index 0000000..b48085d --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/wancfg_tdmapi @@ -0,0 +1,45 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --tdm_api --conf_dir=$WAN_BASE +cd $home diff --git a/util/tmp_davidy/wancfg_zaptel/wancfg_zaptel b/util/tmp_davidy/wancfg_zaptel/wancfg_zaptel new file mode 100755 index 0000000..1d34411 --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/wancfg_zaptel @@ -0,0 +1,45 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --conf_dir=$WAN_BASE +cd $home diff --git a/util/tmp_davidy/wancfg_zaptel/wancfg_zaptel.pl b/util/tmp_davidy/wancfg_zaptel/wancfg_zaptel.pl new file mode 100755 index 0000000..ec5c5fd --- /dev/null +++ b/util/tmp_davidy/wancfg_zaptel/wancfg_zaptel.pl @@ -0,0 +1,2038 @@ +#!/usr/bin/perl +# config-zaptel.pl +# Sangoma Zaptel/TDM API/SMG Configuration Script. +# +# Copyright (c) 2006, Sangoma Technologies Inc. +# +# 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. +# ---------------------------------------------------------------------------- +# Aug 22 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 +# Nov 29 2007 2.8 David Yat Sin Support for BRI cards on Trixbox +# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option +# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode +# Jul 20, 2007 2.5 David Yat Sin silent option +# Jun 13, 2007 Yuan Shen SS7 support +# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major +# changes to script. +# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl +# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong +# context +# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards +# Oct 13, 2006 David Yat Sin Added --opermode and --law option +# Oct 12, 2006 David Yat Sin Initial version +# ============================================================================ + +system('clear'); +print "\n###################################################################"; +print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; +print "\n# v2.9 #"; +print "\n# Sangoma Technologies Inc. #"; +print "\n# Copyright(c) 2007. #"; +print "\n###################################################################\n\n"; + +use strict; +#use warnings; +#use diagnostics; +use Card; +use A10x; +use A10u; +use A20x; +use A50x; + + +my $FALSE = 1; +my $TRUE = 0; +my $zaptelprobe=' '; + +my $etc_dir=""; +my $include_dir=""; +my $module_list=""; +my $module_load=""; +my $module_unload=""; +my $os_type_name=""; +my $dchan_str="dchan"; + +my $os_type_list=`sysctl -a |grep ostype`; +if ($os_type_list =~ m/Linux/){ + $os_type_name="Linux"; + $etc_dir="/etc"; + $module_load="modprobe"; + $module_unload="modprobe -r"; + $module_list="modprobe -l"; + $include_dir="/usr/include"; +}elsif ($os_type_list =~ m/FreeBSD/){ + $os_type_name="FreeBSD"; + $etc_dir="/usr/local/etc"; + $module_load="kldload"; + $module_unload="kldunload"; + $module_list="kldstat"; +}else{ + print("Failed to determine OS type\n"); + print("Exiting...\n"); + exit(1); +} + + +my $startup_string=""; +my $cfg_string=""; +my $first_cfg=1; +my $zaptel_conf=""; +my $zapata_conf=""; +my $bri_conf=""; +my $woomera_conf=""; +my $devnum=1; +my $current_zap_span=1; +my $current_tdmapi_span=1; +#my $current_bri_span=1; +my $current_zap_channel=1; +my $num_analog_devices=0; +my $num_analog_devices_total=0; +my $num_bri_devices=0; +my $num_bri_devices_total=0; +my $num_digital_devices=0; +my $num_digital_devices_total=0; +my $num_ss7_config=0; +my $num_zaptel_config=0; +my $line_media=''; +my $max_chans=0; +my $ss7_tdmvoicechans=''; +my $ss7_array_length=0; + + + +my $device_has_hwec=$FALSE; +my $device_has_normal_clock=$FALSE; +my @device_normal_clocks=("0"); + +my $is_tdm_api=$FALSE; + +my $def_femedia=''; +my $def_feframe=''; +my $def_feclock=''; +my $def_bri_option=''; +my $def_signalling=''; +my $def_switchtype=''; +my $def_zapata_context=''; +my $def_zapata_group=''; +my $def_te_ref_clock=''; +my $def_tdmv_dchan=0; +my $def_bri_group=''; +my $def_felcode=''; +my $def_feframe=''; +my $def_te_sig_mode=''; + +my $def_hw_dtmf="YES"; + +my $silent_femedia="T1"; +my $silent_feframe="ESF"; +my $silent_feframe_e1="CRC4"; + +my $silent_felcode="B8ZS"; + +my $silent_feclock="NORMAL"; +my $silent_signalling="PRI CPE"; +my $silent_switchtype="National"; +my $silent_zapata_context="from-pstn"; +my $silent_zapata_group="0"; +my $silent_te_sig_mode='CCS'; + +my $def_bri_country="europe"; +my $def_bri_operator="etsi"; +my $def_bri_conn_type="Point to multipoint"; + +my $is_trixbox = $FALSE; +my $silent = $FALSE; +my $config_zaptel = $TRUE; +my $config_zapata = $TRUE; +my $is_smg = $FALSE; + +my $tdm_api_span_num=0; +my $zaptel_installed=$FALSE; +my $modprobe_list=`$module_list`; + + +read_args(); +check_zaptel(); +my $current_dir=`pwd`; +chomp($current_dir); +my $cfg_dir='tmp_cfg'; +my $curdircfg="$current_dir"."/"."$cfg_dir"; + +unless ( -d $curdircfg ) { + $curdircfg = "mkdir " . $curdircfg; + system ($curdircfg); +} + + +my $debug_info_file="$current_dir/$cfg_dir/debug_info"; +my @hwprobe=`wanrouter hwprobe verbose`; + +my $wanpipe_conf_dir="$etc_dir/wanpipe"; +my $asterisk_conf_dir="$etc_dir/asterisk"; + +my $wanrouter_rc_template="$current_dir/templates/wanrouter.rc.template"; + +my $zaptel_conf_template="$current_dir/templates/zaptel.conf"; +my $zaptel_conf_file="$current_dir/$cfg_dir/zaptel.conf"; +my $zaptel_conf_file_t="$etc_dir/zaptel.conf"; + +my $zapata_conf_template="$current_dir/templates/zapata.conf"; +my $zapata_conf_file="$current_dir/$cfg_dir/zapata.conf"; +my $zapata_conf_file_t="$asterisk_conf_dir/zapata.conf"; + +my $bri_conf_template="$current_dir/templates/smg_bri.conf"; +my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; +my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; + +my $woomera_conf_template="$current_dir/templates/woomera.conf"; +my $woomera_conf_file="$current_dir/$cfg_dir/woomera.conf"; +my $woomera_conf_file_t="$asterisk_conf_dir/woomera.conf"; + +my $date=`date +%F`; +chomp($date); +my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; + +set_zaptel_hwhdlc(); +prepare_files(); +config_t1e1(); +config_bri(); +config_analog(); +summary(); +apply_changes(); +config_boot(); +config_ztcfg_start(); +config_smg_ctrl_start(); +clean_files(); +print "Sangoma cards configuration complete, exiting...\n\n"; + + +#######################################FUNCTIONS################################################## + + +sub set_zaptel_hwhdlc{ + if ((system("grep hdlc_hard_xmit '$include_dir/zaptel/zaptel.h'>/dev/null 2>/dev/null")==0)){ + $dchan_str="hardhdlc"; + } +} +sub config_boot{ + my $script_name="wanrouter"; + my $current_run_level=3; + my $zaptel_start_level=9; + my $zaptel_stop_level=92; + my $wanrouter_start_level=8; + my $wanrouter_stop_level=93; + my $command=''; + my $rc_dir=$etc_dir; + + if ($os_type_list =~ m/FreeBSD/){ + return; + } + my $res=`cat $etc_dir/inittab |grep id`; + if ($res =~ /id:(\d+):initdefault/){ + $current_run_level=$1; +# print "Current boot level is $current_run_level\n"; + } else { + print "Warning: Failed to determine init boot level, assuming 3\n"; + $current_run_level=3; + } + + + print "\nWanrouter boot scripts configuration...\n\n"; + print "Removing existing $script_name boot scripts..."; + $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; + if(system($command) == 0){ + print "OK\n"; + } else { + print "Not installed\n"; + } + if($num_ss7_config!=0){ + $script_name="smgss7_init_ctrl"; + } + + print ("Would you like $script_name to start on system boot?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + #examine system bootstrap files + $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$rc_dir; + } else { + $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$etc_dir."/rc.d"; + } else { + print "Failed to locate boostrap directory\n"; + print "wanrouter boot scripts will not be installed\n"; + return; + } + } + + if($zaptel_installed==$TRUE){ + print "Verifying Zaptel boot scripts..."; + #find zaptel start scripts + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; + $res=`$command`; + if ($res =~ /.*S(\d+)zaptel/){ + $zaptel_start_level=$1; + print "Enabled (level:$zaptel_start_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_start_level"; + } + } else { + print "Not installed\n"; + $zaptel_start_level=0; + } + + #find zaptel stop scripts + print "Verifying Zaptel shutdown scripts..."; + $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find ".$rc_dir."/rc6.d/*zaptel"; + $res=`$command`; + if ($res =~ /.*K(\d+)zaptel/){ + $zaptel_stop_level=$1; + print "Enabled (level:$zaptel_stop_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; + } + } else { + print "Not installed\n"; + $zaptel_stop_level=0; + } + if ($zaptel_start_level != 0){ + $wanrouter_start_level=$zaptel_start_level-1; + } + if ($zaptel_stop_level != 0){ + $wanrouter_stop_level=$zaptel_stop_level+1; + } + } + my $wanrouter_start_script=''; + if($wanrouter_start_level < 10){ + $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; + } else { + $wanrouter_start_script="S".$wanrouter_start_level.$script_name; + } + my $wanrouter_stop_script=''; + if($wanrouter_stop_level < 10){ + $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; + } else { + $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; + } + + $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; + if(system($command) !=0){ + $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; + if(system($command) !=0){ + print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; + print "$script_name boot scripts not installed\n"; + return; + } + } + print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; + if(system($command) !=0){ + print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; + print "$script_name start scripts not installed\n"; + return; + } + } + + print "Enabling $script_name shutdown scripts ...(level:$wanrouter_stop_level)\n"; + @run_levels= ("0","1","6"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; + if(system($command) !=0){ + print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; + print "$script_name stop scripts not installed\n"; + return; + } + } + } + +} + + +sub config_ztcfg_start{ + if ($num_zaptel_config ==0){ + return; + } + my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) != 0){ + #Zaptel init scripts not installed, prompt for wanpipe_zaptel_start_script + print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + exec_command("cp -f $current_dir/templates/zaptel_cfg_script $wanpipe_conf_dir/scripts/start"); + } + } +} + +sub config_smg_ctrl_start{ + if($num_bri_devices == 0){ + return; + } + print ("Would you like smg_ctrl to start/stop on wanrouter start?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite + my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; + } else { + $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; + } + + if (system($command) == 0){ + print "smgbri start script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + + $command="cp -f ".$current_dir."/templates/smgbri_stop_script ".$wanpipe_conf_dir."/scripts/stop"; + if (system($command) == 0){ + print "smgbri start script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + } +} + +sub check_zaptel{ + if ($modprobe_list =~ /zaptel.ko/){ + $zaptel_installed=$TRUE; + } +} + +sub apply_changes{ + my $asterisk_command=''; + my $bri_command=''; + my $asterisk_restart=$FALSE; + my $res=''; + + system('clear'); + + if($silent==$TRUE){ + $res="Stop now"; + }elsif($is_tdm_api==$TRUE){ + print "\n Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", + "Do not save cfg: Exit", + ""); + }else{ + print "\nZaptel and Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", + "Save cfg: Restart Asterisk & Wanpipe when convenient", + "Save cfg: Stop Asterisk & Wanpipe now", + "Save cfg: Stop Asterisk & Wanpipe when convenient", + "Do not save cfg: Exit", + ""); + } + + + if ($res =~ m/Exit/){ + print "No changes made to your configuration files\n"; + exit 0; + } + if ($res =~ m/now/){ + $asterisk_command='stop now'; + } else { + $asterisk_command='stop when convenient'; + } + + if ($res =~ m/Restart/){ + $asterisk_restart=$TRUE; + } else { + $asterisk_restart=$FALSE; + } + + if ($is_trixbox==$TRUE){ + exec_command("amportal stop"); + unload_zap_modules(); + } elsif ($is_tdm_api==$FALSE ){ + if (`(pidof asterisk)` != 0 ){ + print "\nStopping Asterisk...\n"; + exec_command("asterisk -rx \"$asterisk_command\""); + sleep 2; + while (`(pidof asterisk)` != 0 ){ + if ($asterisk_command eq "stop now"){ + print "Failed to stop asterisk using command: \'$asterisk_command\' \n"; + my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes"); + my $res=&prompt_user_list(@options,""); + + if ( $res =~ m/Force Stop/){ + execute_command("kill -KILL \$(pidof asterisk)"); + } elsif ( $res =~ m/Exit/ ){ + exit(1); + } else { + print "Waiting for asterisk to stop...\n"; + sleep 5; + exec_command("asterisk -rx \"$asterisk_command\""); + } + } else { + #stop when convenient option was selected + print "Waiting for asterisk to stop...\n"; + sleep 3; + } + } + + + + + + }else { + print "\nAsterisk is not running...\n"; + } + + } + + if($num_bri_devices != 0){ + exec_command("/usr/sbin/smg_ctrl stop"); + } + + print "\nStopping Wanpipe...\n"; + exec_command("wanrouter stop all"); + + if ($zaptel_installed==$TRUE){ + if($is_tdm_api==$FALSE){ + print "\nUnloading Zaptel modules...\n"; + unload_zap_modules(); + } + } + + print "\nRemoving old configuration files...\n"; + + exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); + + gen_wanrouter_rc(); + + print "\nCopying new Wanpipe configuration files...\n"; + copy_config_files(); + if($num_bri_devices != 0){ + print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; + exec_command("cp -f $bri_conf_file $bri_conf_file_t"); + exec_command("cp -f $woomera_conf_file $woomera_conf_file_t"); + } + + if ($zaptel_installed==$TRUE){ + if($config_zaptel==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; + exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); + } + } + } + + if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; + exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); + } + } + + if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ + print "\nStarting Wanpipe...\n"; + exec_command("wanrouter start"); + + if($num_bri_devices != 0){ + print "Loading SMG BRI...\n"; + sleep 2; + exec_command("/usr/sbin/smg_ctrl start"); + } + +# if ( ! -e "/$wanpipe_conf_dir/scripts/start" & $is_trixbox==$FALSE && $is_smg==$FALSE ){ + if ($num_zaptel_config != 0){ + print "Loading Zaptel...\n"; + sleep 2; + exec_command("ztcfg -v"); +# print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); +# if (&prompt_user_list("YES","NO","") eq 'YES'){ +# exec_command("cp -f $wanpipe_conf_dir/samples/wanpipe_zaptel_start $wanpipe_conf_dir/scripts/start"); +# } + } + if ($is_trixbox==$TRUE){ + print "\nStarting Amportal...\n"; + exec_command("amportal start"); + sleep 2; + }elsif($config_zapata==$TRUE){ + print "\nStarting Asterisk...\n"; + exec_command("asterisk"); + sleep 2; + + print "\nListing Asterisk channels...\n\n"; + exec_command("asterisk -rx \"zap show channels\""); + print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; + }else{ + } + } + print "\nWanrouter start complete...\n"; +} + + + +sub save_debug_info{ + my $version=`wanrouter version`; + chomp($version); + + my $uname=`uname -a`; + chomp($uname); + + my $issue=''; + + if ($os_type_list =~ m/Linux/){ + $issue=`cat $etc_dir/issue`; + chomp($issue); + } + + my $debug_info="\n"; + $debug_info.="===============================================================\n"; + $debug_info.=" SANGOMA DEBUG INFO FILE \n"; + $debug_info.=" Generated on $date \n"; + $debug_info.="===============================================================\n"; + + $debug_info.="\n\nwanrouter hwprobe\n"; + $debug_info.="@hwprobe\n"; + $debug_info.="\nwanrouter version\n"; + $debug_info.="$version\n"; + $debug_info.="\nKernel \"uname -a\"\n"; + $debug_info.="$uname\n"; + if ($os_type_list =~ m/Linux/){ + $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; + $debug_info.="$issue\n"; + } + $debug_info.="EOF\n"; + + open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; + print FH $debug_info; + close (FH); + exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); +} + +sub get_zapata_context{ + my ($card_model,$card_port)=@_; + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("Select dialplan context for AFT-A%s on port %s\n", $card_model, $card_port); + my $res = &prompt_user_list(@options,$def_zapata_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_zapata_context); + } + + $context=$res_context; + }elsif($res eq $def_zapata_context){ + $context=$def_zapata_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + $context=$silent_zapata_context; + } + $def_zapata_context=$context; + return $context; +} + +sub gen_wanrouter_rc{ + #update wanpipe startup sequence + my $rcfile=""; + if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { + open (FH,"$wanrouter_rc_template"); + } + while () { + $rcfile .= $_; + } + close (FH); + open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); + $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; + print FH $rcfile; + close (FH); +} + +sub prepare_files{ + + if ($is_trixbox==$TRUE){ + $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; + $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; + $zapata_conf_file_t="$asterisk_conf_dir/zapata-auto.conf"; + } + + if ($silent==$FALSE){ + if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ + print "Would you like to generate $zapata_conf_file_t\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $config_zapata = $FALSE; + } + } + } + +#remove temp files + my $tmp_cfg_dir="$current_dir"."/"."$cfg_dir"; + if ( -d "$current_dir"."/"."$cfg_dir") { + exec_command("rm -f $current_dir/$cfg_dir/*"); + } +#backup existing configuration files + if ( -f $zaptel_conf_file_t ) { + exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); + } + + if ( -f $zapata_conf_file_t ) { + exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); + } +} + +sub clean_files{ + exec_command("rm -rf $current_dir/$cfg_dir"); +} + + +sub write_zapata_conf{ + my $zp_file=""; + open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + + $zp_file.=$zapata_conf; + + open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; + print FH $zp_file; + close(FH); +} + +sub copy_config_files{ + my @wanpipe_files = split / /, $cfg_string; + exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc $wanpipe_conf_dir"); + foreach my $wanpipe_file (@wanpipe_files) { + exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf $wanpipe_conf_dir"); + } +} + +sub unload_zap_modules{ + my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); + foreach my $module (@modules_list) { + if ($modprobe_list =~ m/$module/){ + exec_command("$module_unload $module"); + } + } +} + +sub write_zaptel_conf{ + my $zp_file=""; + open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + $zp_file=$zp_file.$zaptel_conf; + open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; + print FH $zp_file; + close(FH); +} + +sub summary{ + if($devnum==1){ + system('clear'); + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); + exit 0; + }else{ + if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ + write_zaptel_conf(); + } + if ($num_bri_devices != 0 ){ + write_bri_conf(); + write_woomera_conf(); + } + if ($config_zapata==$TRUE){ + write_zapata_conf(); + } + save_debug_info(); + system('clear'); + my $file_list = 1; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); + print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); + print(" $num_bri_devices_total ISDN BRI card(s) detected, $num_bri_devices configured\n"); + + print "\nConfigurator has created the following files:\n"; + print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; + $file_list++; + + if ($num_bri_devices != 0){ + print "\t$file_list. sangoma_brid config file $wanpipe_conf_dir/smg_bri\n"; + $file_list++; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; + } + + if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ + print "\n\nYour original configuration files will be saved to:\n"; + $file_list=1; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. $zaptel_conf_file_t.bak \n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. $zapata_conf_file_t.bak \n\n"; + } + + print "\nYour configuration has been saved in $debug_tarball.\n"; + print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } +} + + +sub exec_command{ + my @command = @_; + if (system(@command) != 0 ){ + print "Error executing command:\n@command\n\n"; + } + return $?; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "def=\"$defaultValue\": "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $defaultValue = @list[$#list]; + + my $i; + my $valid = 0; + for $i (0..$#list-1) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + my $list_sz = $#list; + print "[1-$list_sz"; + if ( ! $defaultValue eq ''){ + print ", ENTER=\'$defaultValue\']:"; + }else{ + print "]:"; + } + $| = 1; + $_ = ; + chomp; + if ( $_ eq '' & ! $defaultValue eq ''){ + print "\n"; + return $defaultValue; + } + + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $list_sz) { + print "\nError: Invalid option, input a value between 1 and $list_sz \n"; + } else { + print "\n"; + return @list[$1-1] ; + } + } else { + print "\nError: Invalid option, input an integer\n"; + } + } +} + +sub read_args { + my $arg_num; + foreach $arg_num (0 .. $#ARGV) { + $_ = $ARGV[$arg_num]; + if( /^--trixbox$/){ + $is_trixbox=$TRUE; + }elsif ( /^--tdm_api/){ + $is_tdm_api=$TRUE; + }elsif ( /^--smg$/){ + $is_smg=$TRUE; + }elsif ( /^--silent$/){ + $silent=$TRUE; + }elsif ( /^--no-zapata$/){ + $config_zapata=$FALSE; + }elsif ( /^--no-zaptel$/){ + $config_zaptel=$FALSE; + }elsif ( $_ =~ /--fe_media=(\w+)/){ + $silent_femedia=$1; + if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ + printf("Invalid value for fe_media, should be T1/E1\n"); + exit(1); + } + }elsif ( $_ =~ /--fe_frame=(\w+)/){ + $silent_feframe=$1; + if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ + printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); + exit(1); + } + }elsif ( $_ =~ /--fe_clock=(\w+)/){ + $silent_feclock=$1; + if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ + printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); + exit(1); + } + }elsif ( $_ =~ /--signalling=(\w+)/){ + my $tmp_signalling=$1; + if ($tmp_signalling eq 'em'){ + $silent_signalling="E & M"; + }elsif ($tmp_signalling eq 'em_w'){ + $silent_signalling="E & M Wink"; + }elsif ($tmp_signalling eq 'pri_cpe'){ + $silent_signalling="PRI CPE"; + }elsif ($tmp_signalling eq 'pri_net'){ + $silent_signalling="PRI NET"; + }elsif ($tmp_signalling eq 'fxs_ls'){ + $silent_signalling="FXS - Loop Start"; + }elsif ($tmp_signalling eq 'fxs_gs'){ + $silent_signalling="FXS - Ground Start"; + }elsif ($tmp_signalling eq 'fxs_ks'){ + $silent_signalling="FXS - Kewl Start"; + }elsif ($tmp_signalling eq 'fxo_ls'){ + $silent_signalling="FXO - Loop Start"; + }elsif ($tmp_signalling eq 'fxo_gs'){ + $silent_signalling="FXO - Ground Start"; + }elsif ($tmp_signalling eq 'fxo_ks'){ + $silent_signalling="FXO - Kewl Start"; + }else{ + printf("Invalid option for --signalling, options are\n"); + printf("\t pri_cpe/pri_net/em/em_w\n"); + printf("\t em/em_w\n"); + printf("\t fxo_ls/fxo_gs/fxo_ks\n"); + printf("\t fxs_ls/fxs_gs/fxs_ks\n"); + exit(1); + } + }elsif ( $_ =~ /--conf_dir=(.*)/){ + $etc_dir=$1; + if (! -d $etc_dir){ + printf("Error: directory $1 does not exist\n"); + exit(1); + } + } + } + + if ($is_trixbox==$TRUE){ + print "\nGenerating configuration files for Trixbox\n"; + } + if ($is_smg==$TRUE){ + print "\nGenerating configuration files for SS7\n"; + } + if ($is_tdm_api==$TRUE){ + $config_zapata = $FALSE; + } + +} + +#------------------------------BRI FUNCTIONS------------------------------------# +sub get_bri_country { + $def_bri_country = "europe"; + return $def_bri_country; +} + +sub get_bri_group{ + my $group; + my $res_group=&prompt_user("\nInput the group for this port\n",$def_bri_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ + print "Invalid group, input an integer greater than 0\n"; + $res_group=&prompt_user("Input the group for this port",$def_bri_group); + } + $group=$res_group; + $def_bri_group=$group; + return $def_bri_group; +} + + +sub get_bri_operator { +#warning returning ETSI + $def_bri_operator = "etsi"; + return $def_bri_operator; + + + + my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", + "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", + "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); + + my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); + + my $res = &prompt_user_list(@options,$def_switchtype); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_operator=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + +sub write_bri_conf{ + my $bri_file=""; + open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; + while () { + $bri_file .= $_; + } + close (FH); + $bri_file=$bri_file.$bri_conf; + open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; + print FH $bri_file; + close(FH); +} + +sub write_woomera_conf{ + my $woomera_file=""; + open(FH, "$woomera_conf_template") or die "cannot open $woomera_conf_template"; + while () { + $woomera_file .= $_; + } + close (FH); + $woomera_file=$woomera_file.$woomera_conf; + open(FH, ">$woomera_conf_file") or die "cannot open $woomera_conf_file"; + print FH $woomera_file; + close(FH); +} + + +sub get_bri_conn_type{ + my $conn_type; + + my @options = ( "Point to multipoint", "Point to point"); + my @options_val = ("point_to_multipoint", "point_to_point"); + + my $res = &prompt_user_list(@options,$def_bri_conn_type); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_conn_type=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid BRI connection type\n"; + exit 1; +} + + + + +sub config_bri{ + if($is_smg!=$TRUE && $is_trixbox==$FALSE){ + return; + } + my $a50x; + if (!$first_cfg) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring ISDN BRI cards [A500]\n"; + print "------------------------------------\n"; + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ + $skip_card=$FALSE; + if ($1 eq '500'){ + my $card = eval {new Card(); } or die ($@); + + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + + my $hwec=0; + if($6 gt 0){ + $hwec=1; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + + if ($card->card_model eq '500'){ + $num_bri_devices_total++; + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + +select_bri_option: + print "\nWould you like to configure A$1 port $5 on slot:$3 bus:$4\n"; + my @options=("YES", "NO", "Exit"); + $def_bri_option=&prompt_user_list(@options,$def_bri_option); + if($def_bri_option eq 'YES'){ + $skip_card=$FALSE; + $bri_conf.="\n;Sangoma A$1 port $5 [slot:$3 bus:$4 span:$current_tdmapi_span]"; + }elsif($def_bri_option eq 'NO'){ + $skip_card=$TRUE; + }else{ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } else { + goto select_bri_option; + } + } + if ($skip_card==$FALSE){ +# print "A$1 port:$5 configured on slot:$3 bus:$4 span:$devnum\n"; +# prompt_user("Press any key to continue"); + + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + $a50x = eval {new A50x(); } or die ($@); + $a50x->card($card); + $a50x->fe_line($5); + $devnum++; + $num_bri_devices++; + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + $a50x->gen_wanpipe_conf(); + }else{ + print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; + prompt_user("Press any key to continue"); + } + + } + } + }elsif ( $dev =~ /(\d+):NT/ & $skip_card==$FALSE){ + printf("\nConfiguring port %d as NT\n", $a50x->fe_line()); + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $context; + my $group; + my $bri_pos=$a50x->card->tdmv_span_no; + my $conn_type=get_bri_conn_type(); + my $country=get_bri_country(); + my $operator=get_bri_operator(); + my $context="from-internal"; + + if ($is_trixbox==$TRUE){ + $context="from-internal"; + $group=1; + }else{ + $context="from-internal"; + $group=get_bri_group(); + } + $bri_conf.=$a50x->gen_bri_conf($bri_pos, "bri_nt" , $group, $country, $operator, $conn_type); + $woomera_conf.=$a50x->gen_woomera_conf($group, $context); + }elsif ( $dev =~ /(\d+):TE/ & $skip_card==$FALSE){ + printf("\nConfiguring port %d as TE\n", $a50x->fe_line()); + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $context; + my $group; + my $bri_pos=$a50x->card->tdmv_span_no; + my $conn_type=get_bri_conn_type(); + my $country=get_bri_country(); + my $operator=get_bri_operator(); + + if ($is_trixbox==$TRUE){ + $context="from-zaptel"; + $group=2; + }else{ + $context="from-woomera"; + $group=get_bri_group(); + } + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); + $woomera_conf.=$a50x->gen_woomera_conf($group, $context); + } + } +# prompt_user("Press any key to continue"); + if($num_bri_devices_total!=0){ + print("\nISBN BRI card configuration complete\n\n"); + prompt_user("Press any key to continue"); + } else { + print("\nNo Sangoma ISDN BRI cards detected\n\n"); + prompt_user("Press any key to continue"); + + } +} + + + + + +#------------------------------T1/E1 FUNCTIONS------------------------------------# + +sub get_te_ref_clock{ + my @list_normal_clocks=@_; + my @f_list_normal_clocks; + my $f_port; + foreach my $port (@list_normal_clocks) { + if ($port eq '0'){ + $f_port = "Free run"; +} else { + $f_port = "Port ".$port; +} + push(@f_list_normal_clocks, $f_port); +} + + my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); + my $i; + + for $i (0..$#f_list_normal_clocks){ + if ( $res eq @f_list_normal_clocks[$i] ){ + return @list_normal_clocks[$i]; +} +} + + print "Internal error: Invalid reference clock\n"; + exit 1; + +} + + +sub prompt_user_hw_dchan{ + my ($card_model, $port, $port_femedia) = @_; + my $res_dchan=''; + my $dchan; + + printf("Hardware HDLC can be performed on the data channel.\n"); +prompt_hw_dchan: + my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); + while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ + print "Invalid channel, input an integer (0 for unused).\n"; + $res_dchan=&prompt_user("Select the data channel","0"); + } + if ( $res_dchan < 0){ + printf("Error: channel cannot have negative value\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ( $port_femedia eq 'T1' && $res_dchan > 24){ + printf("Error: only 24 channels available on T1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + }elsif ($port_femedia eq 'E1' && $res_dchan > 31){ + printf("Error: only 31 channels available on E1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ($res_dchan == 0){ + printf("HW HDLC channel not used\n"); + }else{ + printf("HW HDLC channel set to:%d\n", $res_dchan); + } + return $res_dchan; +} + + + +sub get_zapata_group{ + my ($card_model,$card_port,$context)=@_; + my $group=''; + if($is_trixbox==$TRUE){ + if($context eq "from-zaptel"){ + $group=0; + return $group; + }elsif($context eq "from-internal"){ + $group=1; + return $group; + }else{ + print "Internal error:invalid group for Trixbox\n"; + } + }else{ + if($context eq "from-pstn"){ + $group=0; + }elsif($context eq "from-internal"){ + $group=1; + }else{ + my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)){ + print "Invalid group, input an integer.\n"; + $res_group=&prompt_user("Input the group for this port",$def_zapata_group); + } + $group=$res_group; + $def_zapata_group=$group; + } + } + + return $group; +} + + + +sub prompt_hw_dtmf { + print("Would you like to enable hardware DTMF detection?\n"); + my @options = ("YES","NO"); + $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); + return $def_hw_dtmf; + +} + +sub get_pri_switchtype { + my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); + my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); + my $res = &prompt_user_list(@options,$def_switchtype); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_switchtype=@options[$i]; + return @options_val[$i]; +} +} + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + + +sub gen_ss7_voicechans{ + my @ss7_array = @_; + my $T1CHANS = pop(@ss7_array); + my $count = @ss7_array; + my $output =''; + my $chan_in = 1; + my $chan_de = 0; + my $flag = 0; + my $i = 0; + my $j = 0; + + while($i < $count){ + $j = $i + 1; + if ($ss7_array[$i] > 2 && $i == 0){ + $chan_de = $ss7_array[$i] - 1; + $output .= "1-$chan_de"; + $flag = 1; + }elsif ($ss7_array[$i] == 2 && $i == 0){ + $output .= "1"; + $flag = 1; + } + + if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ + goto Incrementing; + }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ + goto Incrementing; + } + + if ($i < ($count-1)){ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < ($ss7_array[$j]-1)){ + $chan_de = $ss7_array[$j] - 1; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$chan_in"; + }else{ + $output .= "$chan_in"; + $flag = 1; + } + } + }else{ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < $T1CHANS){ + $chan_de = $T1CHANS; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$T1CHANS"; + }else{ + $output .= "$T1CHANS"; + $flag = 1; + } + } + } + +Incrementing: + $i++; + } + return $output; +} + +sub prompt_user_ss7_chans{ + my @ss7_string = @_; + my $def_ss7_group_chan = ''; + + my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + +CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ + print("ERROR: Invalid channel number, input an integer only.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); +} + if ($line_media eq 'T1'){ + while ($ss7_group_chan>24 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 24 channels in T1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +}elsif ($line_media eq 'E1'){ + while ($ss7_group_chan>31 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 31 channels in E1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +} + return $ss7_group_chan; +} + + + + + + +sub config_t1e1{ + if (!$first_cfg) { + system('clear'); + } + print "---------------------------------------------\n"; + print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; + print "---------------------------------------------\n"; + + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + + if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ + #do not count analog devices + $num_digital_devices_total++; + } + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + + my $hwec=0; + if ( $dev =~ /HWEC=(\d+)/){ + if($1 gt 0){ + $hwec=1; + } + } + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + my $port=$6; + if ($6 eq 'PRI') { + $port=$5; + } + + if ( $card->card_model eq '101' | + $card->card_model eq '102' | + $card->card_model eq '104' | + $card->card_model eq '108' ){ + if (!$first_cfg) { + system('clear'); + } + if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ + print "A$1 detected on slot:$3 bus:$4\n"; + $device_has_normal_clock=$FALSE; + @device_normal_clocks = ("0"); + } + if (!$first_cfg) { + system('clear'); + } + $first_cfg=0; + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; + print "$msg"; + print "-----------------------------------------------------------\n"; + my $fe_media = ''; + if ($silent==$TRUE){ + $fe_media = $silent_femedia; + } else { + printf ("\nSelect media type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + my @options = ("T1", "E1", "Unused","Exit"); + $fe_media = prompt_user_list( @options, $def_femedia); + } + + if ( $fe_media eq 'Exit'){ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } + }elsif ( $fe_media eq 'Unused'){ + $def_femedia=$fe_media; + my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; + print "$msg"; + prompt_user("Press any key to continue"); + }else{ + if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ + $device_has_hwec=$TRUE; + } + + $def_femedia=$fe_media; + $cfg_string.="wanpipe$devnum "; + my $a10x; + + if ($1 !~ m/104/ && $2 !~ m/SH/) { + $a10x = eval {new A10u(); } or die ($@); + $a10x->card($card); + if ($5 eq "A") { + $a10x->fe_line("1"); + } else { + $a10x->fe_line("2"); + } + } else { + $a10x = eval {new A10x(); } or die ($@); + if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + $a10x->card($card); + $a10x->fe_line($6); + } + + $card->first_chan($current_zap_channel); + $a10x->fe_media($fe_media); + if ( $fe_media eq 'T1' ){ + $max_chans = 24; + $line_media = 'T1'; + + #$def_te_sig_mode=''; + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + + + if ($silent==$FALSE){ + printf ("Configuring port %s on AFT-A%s as: %s, coding:%s, framing:%s.\n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe, + $port); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("B8ZS", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("ESF", "D4"); + $def_feframe= &prompt_user_list(@options, $def_feframe); + } + + + } else { + $def_felcode=$silent_felcode; + } + + + }else{ #fe_media = E1 + $max_chans = 31; + $line_media = 'E1'; + + + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("HDB3", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("CRC4", "NCRC4","UNFRAMED"); + $def_feframe = &prompt_user_list(@options, $def_feframe); + +# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); +# my @options = ("CCS - Clear channel signalling ", "CAS"); +# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); + + } + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode on AFT-A%s port %s\n",$card->card_model, $port); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + } else { + $def_te_sig_mode="CAS"; + } + + + } else { + $def_felcode=$silent_felcode; + } + + + } + $a10x->fe_lcode($def_felcode); + $a10x->fe_frame($def_feframe); + if($silent==$FALSE){ + my @options = ("NORMAL", "MASTER"); + printf ("Select clock for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_feclock=&prompt_user_list(@options, $def_feclock); + } else { + $def_feclock=$silent_feclock; + } + + $a10x->fe_clock($def_feclock); + if ( $def_feclock eq 'NORMAL') { + $device_has_normal_clock=$TRUE; + push(@device_normal_clocks, $a10x->fe_line); + } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ + printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", + $card->card_model, + $port, + $card->pci_slot, + $card->pci_bus); + printf(" Free run: Use internal oscillator on card [default] \n"); + printf(" Port N: Sync with clock from port N \n\n"); + + printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); + $a10x->te_ref_clock($def_te_ref_clock); + } + + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + } + + + + my @options=""; + if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_smg==$TRUE && $zaptel_installed==$FALSE){ + @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_tdm_api==$TRUE){ + $def_signalling="TDM API"; + } else { + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); + } + if ($silent==$FALSE){ + if( $is_tdm_api == $FALSE){ + printf ("Select signalling type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_signalling=&prompt_user_list(@options,$def_signalling); + } + } else { + $def_signalling=$silent_signalling; + } + $a10x->signalling($def_signalling); + + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + + } else { + $def_te_sig_mode="CAS"; + } + $a10x->te_sig_mode($def_te_sig_mode); + + my $ss7_chan; + my $ss7_group_start; + my $ss7_group_end; + my @ss7_chan_array; + my @ss7_sorted; + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_option(1); + print("Choose an option below to configure SS7 signalling channels:\n"); + my @options =("Configure individual signalling channels(e.g #1,#10)", + "Configure consecutive signalling channels(e.g #1-#16)"); + my $res = &prompt_user_list(@options, ""); + if ( $res eq 'Configure individual signalling channels(e.g #1,#10)'){ + goto SS7CHAN; + while (1){ + print("\nAny other SS7 signalling channel to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7CHAN: + $ss7_chan = prompt_user_ss7_chans('Specify the channel for SS7 signalling(24 for T1? 16 for E1?)'); + push(@ss7_chan_array, $ss7_chan); + $ss7_array_length = @ss7_chan_array; + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + }else{ + goto SS7GROUP; + while(1){ + print("\nAny other SS7 consecutive signalling channels to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7GROUP: + $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); + $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); + if ($ss7_group_start > $ss7_group_end){ + print("The starting channel number is bigger than the ending one!\n"); + goto SS7GROUP; + } + my $i = 0; + for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ + push(@ss7_chan_array, $i); + my @remove_duplicate; + @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); + $ss7_array_length = @ss7_chan_array; + + if ($ss7_array_length > $max_chans){ + print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); + + @ss7_chan_array = (); + goto SS7GROUP; + } + } + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + } + +ENDSS7CONFIG: + + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); + my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); + $ss7_tdmvoicechans = $ss7_voicechans; + + if ($ss7_voicechans =~ m/(\d+)/){ + $a10x->ss7_tdminterface($1); + } + + $a10x->ss7_tdmchan($ss7_voicechans); + + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + + #wanrouter start/stop for signalling span is controlled by ss7boxd + #$startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ + $a10x->ss7_option(2); + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + + }elsif ($a10x->signalling eq 'TDM API'){ + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); + } + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + }else{ + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $startup_string.="wanpipe$devnum "; + $current_zap_span++; + $current_zap_channel+=$max_chans; + } + + + + if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ + if ($silent==$FALSE && $config_zapata==$TRUE){ + printf ("Select switchtype for AFT-A%s on port %s \n", $card->card_model, $port); + $a10x->pri_switchtype(get_pri_switchtype()); + } else { + $a10x->pri_switchtype($silent_switchtype); + } + } + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_subinterface(1); + $a10x->gen_wanpipe_ss7_subinterfaces(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(2); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + my $ss7_element; + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + + $a10x->gen_wanpipe_conf(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + }else{ + $a10x->gen_wanpipe_conf(); + } + + if ($is_smg==$TRUE && $config_zapata==$FALSE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' + | $a10x->signalling eq 'No Signaling (Voice Only)')){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ + + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + } + }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + }elsif ($is_tdm_api == $FALSE){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + $devnum++; + $num_digital_devices++; + my $msg ="\n\nPort ".$port." on A".$card->card_model." configuration complete...\n"; + print "$msg"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + } + + + } + + } + } + if($num_digital_devices_total!=0){ + print("\nT1/E1 card configuration complete.\n"); + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + $first_cfg=0; + } +# close SCR; +} + + +#------------------------------ANALOG FUNCTIONS------------------------------------# + + +sub config_analog{ + + if($is_tdm_api==$TRUE){ + return; + } + my $a20x; + if (!$first_cfg) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring analog cards [A200/A400]\n"; + print "------------------------------------\n"; + + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ + $skip_card=$FALSE; + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + my $hwec=$7; + if ($hwec==0){ + $card->hwec_mode('NO'); + } + else{ + $card->hwec_mode('YES'); + } + if ($card->card_model eq '200' | $card->card_model eq '400'){ + $num_analog_devices_total++; + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + if($is_trixbox==$FALSE){ + print "\nWould you like to configure A$1 on slot:$3 bus:$4\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $skip_card=$TRUE; + } + } + if ($skip_card==$FALSE){ + + $a20x = eval {new A20x(); } or die ($@); + $a20x->card($card); + $card->first_chan($current_zap_channel); + + if ( $device_has_hwec==$TRUE){ + print "Will this AFT-A$1 synchronize with an existing Sangoma T1/E1 card?\n"; + print "\n WARNING: for hardware and firmware requirements, check:\n"; + print " http://wiki.sangoma.com/t1e1analogfaxing\n"; + + if (&prompt_user_list(("NO","YES","")) eq 'NO'){ + $a20x->rm_network_sync('NO'); + } else { + $a20x->rm_network_sync('YES'); + } + } + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + } + + + print "A$1 configured on slot:$3 bus:$4 span:$current_zap_span\n"; + prompt_user("Press any key to continue"); + $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + + $current_zap_channel+=24; + my $i; + $devnum++; + $num_analog_devices++; + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + $a20x->gen_wanpipe_conf(); + + }else{ + print "A$1 on slot:$3 bus:$4 not configured\n"; + prompt_user("Press any key to continue"); + } + } + }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-internal"); + $a20x->card->zap_group("1"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); + }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-zaptel"); + $a20x->card->zap_group("0"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); + } + } + if($num_analog_devices_total!=0){ + print("\nAnalog card configuration complete\n\n"); + prompt_user("Press any key to continue"); + } + +} + diff --git a/util/wan_aftup/A101dm_0040_V31.BIN b/util/wan_aftup/A101dm_0040_V31.BIN deleted file mode 100644 index 0fa38aa..0000000 Binary files a/util/wan_aftup/A101dm_0040_V31.BIN and /dev/null differ diff --git a/util/wan_aftup/A101dm_0040_V34.BIN b/util/wan_aftup/A101dm_0040_V34.BIN new file mode 100644 index 0000000..a21f73b Binary files /dev/null and b/util/wan_aftup/A101dm_0040_V34.BIN differ diff --git a/util/wan_aftup/A102dm_0040_V31.BIN b/util/wan_aftup/A102dm_0040_V31.BIN deleted file mode 100644 index fd9b527..0000000 Binary files a/util/wan_aftup/A102dm_0040_V31.BIN and /dev/null differ diff --git a/util/wan_aftup/A102dm_0040_V33.BIN b/util/wan_aftup/A102dm_0040_V33.BIN new file mode 100644 index 0000000..33262f1 Binary files /dev/null and b/util/wan_aftup/A102dm_0040_V33.BIN differ diff --git a/util/wan_aftup/A104d_0100_V24.BIN b/util/wan_aftup/A104d_0100_V24.BIN deleted file mode 100644 index bb377a7..0000000 Binary files a/util/wan_aftup/A104d_0100_V24.BIN and /dev/null differ diff --git a/util/wan_aftup/A104d_0100_V25.BIN b/util/wan_aftup/A104d_0100_V25.BIN deleted file mode 100644 index 90bbc77..0000000 Binary files a/util/wan_aftup/A104d_0100_V25.BIN and /dev/null differ diff --git a/util/wan_aftup/A104d_0100_V26.BIN b/util/wan_aftup/A104d_0100_V26.BIN new file mode 100644 index 0000000..cce4b5d Binary files /dev/null and b/util/wan_aftup/A104d_0100_V26.BIN differ diff --git a/util/wan_aftup/A104dm_0100_V31.BIN b/util/wan_aftup/A104dm_0100_V31.BIN deleted file mode 100644 index 5c703ea..0000000 Binary files a/util/wan_aftup/A104dm_0100_V31.BIN and /dev/null differ diff --git a/util/wan_aftup/A104dm_0100_V33.BIN b/util/wan_aftup/A104dm_0100_V33.BIN new file mode 100644 index 0000000..9ef73a1 Binary files /dev/null and b/util/wan_aftup/A104dm_0100_V33.BIN differ diff --git a/util/wan_aftup/A108dm_0100_V31.BIN b/util/wan_aftup/A108dm_0100_V31.BIN deleted file mode 100644 index de6e4d1..0000000 Binary files a/util/wan_aftup/A108dm_0100_V31.BIN and /dev/null differ diff --git a/util/wan_aftup/A108dm_0100_V33.BIN b/util/wan_aftup/A108dm_0100_V33.BIN new file mode 100644 index 0000000..10fb6bf Binary files /dev/null and b/util/wan_aftup/A108dm_0100_V33.BIN differ diff --git a/util/wan_aftup/A200_0040_V08.BIN b/util/wan_aftup/A200_0040_V08.BIN deleted file mode 100644 index c6563ab..0000000 Binary files a/util/wan_aftup/A200_0040_V08.BIN and /dev/null differ diff --git a/util/wan_aftup/A200_0040_V10.BIN b/util/wan_aftup/A200_0040_V10.BIN deleted file mode 100644 index 7d42e32..0000000 Binary files a/util/wan_aftup/A200_0040_V10.BIN and /dev/null differ diff --git a/util/wan_aftup/A200_0040_V11.BIN b/util/wan_aftup/A200_0040_V11.BIN new file mode 100644 index 0000000..252d531 Binary files /dev/null and b/util/wan_aftup/A200_0040_V11.BIN differ diff --git a/util/wan_aftup/A400_0040_V09.BIN b/util/wan_aftup/A400_0040_V09.BIN deleted file mode 100644 index 0eae506..0000000 Binary files a/util/wan_aftup/A400_0040_V09.BIN and /dev/null differ diff --git a/util/wan_aftup/A400_0040_V10.BIN b/util/wan_aftup/A400_0040_V10.BIN deleted file mode 100644 index 93ad63d..0000000 Binary files a/util/wan_aftup/A400_0040_V10.BIN and /dev/null differ diff --git a/util/wan_aftup/A400_0040_V11.BIN b/util/wan_aftup/A400_0040_V11.BIN new file mode 100644 index 0000000..fd3081d Binary files /dev/null and b/util/wan_aftup/A400_0040_V11.BIN differ diff --git a/util/wan_aftup/ChangeLog.a101dm b/util/wan_aftup/ChangeLog.a101dm index 9b16770..b96f2e8 100644 --- a/util/wan_aftup/ChangeLog.a101dm +++ b/util/wan_aftup/ChangeLog.a101dm @@ -1,6 +1,20 @@ AFT A101dm Firmware Change Log ============================= +Release V33 +----------- +Sep 27 2007 +Type: Recommended A101dm Firmware for echo cancel cards + Fixes issue with hardware echo canceller chip + security. + Supports DTMF detection without hardware echo + cancellation operation. + +Changes: Firmware bug fix for echo canceller + This bug can shut down the driver. + + Note: This bug only afected new Maxim AFT cards with HWEC. + DTMF detection only applies AFT cards with HWEC. Release V31 ----------- diff --git a/util/wan_aftup/ChangeLog.a102dm b/util/wan_aftup/ChangeLog.a102dm index a3ccd0e..e6c6f88 100644 --- a/util/wan_aftup/ChangeLog.a102dm +++ b/util/wan_aftup/ChangeLog.a102dm @@ -1,5 +1,20 @@ AFT A102dm Firmware Change Log ============================= +Release V33 +----------- +Sep 27 2007 + +Type: Recommended A102dm Firmware for echo cancel cards + Fixes issue with hardware echo canceller chip + security. + Supports DTMF detection without hardware echo + cancellation operation. + +Changes: Firmware bug fix for echo canceller + This bug can shut down the driver. + + Note: This bug only afected new Maxim AFT cards with HWEC. + DTMF detection only applies AFT cards with HWEC. Release V31 diff --git a/util/wan_aftup/ChangeLog.a104d b/util/wan_aftup/ChangeLog.a104d index 40fec19..b920f96 100644 --- a/util/wan_aftup/ChangeLog.a104d +++ b/util/wan_aftup/ChangeLog.a104d @@ -1,5 +1,14 @@ AFT A104d Firmware Change Log ============================= +Release V26 +----------- +Sep 27 2007 + +Type: Recommended Firmware for PCI/PCI-Express Cards + Fixes chip security issue. + +Changes: Firmware bug fix for PCI/PCI-Express Cards + This bug can shut down the driver. Release V25 ------------ diff --git a/util/wan_aftup/ChangeLog.a104dm b/util/wan_aftup/ChangeLog.a104dm index 8673c57..35a2767 100644 --- a/util/wan_aftup/ChangeLog.a104dm +++ b/util/wan_aftup/ChangeLog.a104dm @@ -1,5 +1,21 @@ AFT A104dm Firmware Change Log ============================= +Release V33 +----------- +Sep 27 2007 + +Type: Recommended A104dm Firmware for echo cancel cards + Fixes issue with hardware echo canceller chip + security. + Supports DTMF detection without hardware echo + cancellation operation. + +Changes: Firmware bug fix for echo canceller + This bug can shut down the driver. + + Note: This bug only afected new Maxim AFT cards with HWEC. + DTMF detection only applies AFT cards with. + Release V31 ----------- diff --git a/util/wan_aftup/ChangeLog.a108dm b/util/wan_aftup/ChangeLog.a108dm index d4ba6c6..75d5759 100644 --- a/util/wan_aftup/ChangeLog.a108dm +++ b/util/wan_aftup/ChangeLog.a108dm @@ -1,6 +1,22 @@ AFT A108dm Firmware Change Log =============================== +Release V33 +----------- +Sep 27 2007 + +Type: Recommended A108dm Firmware for echo cancel cards + Fixes issue with hardware echo canceller chip + security. + Supports DTMF detection without hardware echo + cancellation operation. + +Changes: Firmware bug fix for echo canceller + This bug can shut down the driver. + + Note: This bug only afected new Maxim AFT cards with HWEC. + DTMF detection only applies AFT cards with HWEC. + Release V31 ----------- Jul 10 2007 diff --git a/util/wan_aftup/ChangeLog.a200 b/util/wan_aftup/ChangeLog.a200 index 5111b66..b3171d7 100644 --- a/util/wan_aftup/ChangeLog.a200 +++ b/util/wan_aftup/ChangeLog.a200 @@ -1,6 +1,21 @@ AFT A200 Firmware Change Log ============================ +Release V11 +----------- +Sep 27 2007 + +Type Recommended update for A200d cards + Fixes bug with echo canceller chip security. + Supports DTMF detection without hardware echo cancellation + operation. + +Changes: Firmware bug fixes for A200d cards + Card fail to load due to echo canceller chip secutiry. + Note: This bug only affects A200 with HWEC + DTMF detecion support only applies to AFT card with + HWEC. + Release V10 ----------- Jun 10 2007 diff --git a/util/wan_aftup/ChangeLog.a400 b/util/wan_aftup/ChangeLog.a400 index aa283fe..698a14a 100644 --- a/util/wan_aftup/ChangeLog.a400 +++ b/util/wan_aftup/ChangeLog.a400 @@ -1,6 +1,21 @@ AFT A400 Firmware Change Log ============================= +Release V11 +----------- +Sep 27 2007 + +Type Recommended update for A400d cards + Fixes bug with echo canceller chip security. + Supports DTMF detection without hardware echo cancellation + operation. + +Changes: Firmware bug fixes for A400d cards + Card fail to load due to echo canceller chip secutiry. + Note: This bug only affects A400 with HWEC + DTMF detecion support only applies to AFT card with + HWEC. + Release V10 ----------- Jun 10 2007 diff --git a/util/wancfg/conf_file_reader.cpp b/util/wancfg/conf_file_reader.cpp index 8893c88..137bd5b 100644 --- a/util/wancfg/conf_file_reader.cpp +++ b/util/wancfg/conf_file_reader.cpp @@ -797,7 +797,7 @@ look_up_t sym_table[] = { WAN_T1_440_550, (void*)"440-550FT" }, { WAN_T1_550_660, (void*)"550-660FT" }, { WAN_E1_120, (void*)"120OH" }, - { WAN_E1_75, (void*)"75OOH" }, + { WAN_E1_75, (void*)"75OH" }, { WAN_NORMAL_CLK, (void*)"NORMAL" }, { WAN_MASTER_CLK, (void*)"MASTER" }, { WAN_TE1_SIG_CAS, (void*)"CAS" }, diff --git a/util/wancfg/conf_file_writer.cpp b/util/wancfg/conf_file_writer.cpp index 9880090..06e27bc 100644 --- a/util/wancfg/conf_file_writer.cpp +++ b/util/wancfg/conf_file_writer.cpp @@ -120,7 +120,7 @@ look_up_t t1_line_build_out_options_table[] = look_up_t e1_line_build_out_options_table[] = { { WAN_E1_120, (void*)"120OH" }, - { WAN_E1_75, (void*)"75OOH" }, + { WAN_E1_75, (void*)"75OH" }, { 1, (void*)"120OH" },//for "zaptel" parsing only { 0, NULL } }; diff --git a/util/wancfg_zaptel/.#wancfg_zaptel.1.5 b/util/wancfg_zaptel/.#wancfg_zaptel.1.5 new file mode 100755 index 0000000..51fba37 --- /dev/null +++ b/util/wancfg_zaptel/.#wancfg_zaptel.1.5 @@ -0,0 +1,45 @@ +#!/bin/sh +home=`pwd` +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_HOME=/etc + META_CONF=/etc/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_HOME=/usr/local/etc + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`/sbin/sysctl -a |grep ostype` +#ostype=`echo $ostype | sed 's/.*: //'` +ostype=`echo $ostype | sed 's/.* //'` + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + + +cd ${WAN_HOME}/wanpipe/wancfg_zaptel +./wancfg_zaptel.pl --conf_dir=$WAN_HOME +cd $home diff --git a/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 b/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 new file mode 100755 index 0000000..1b96e67 --- /dev/null +++ b/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 @@ -0,0 +1,1920 @@ +#!/usr/bin/perl +# config-zaptel.pl +# Sangoma Zaptel/TDM API/SMG Configuration Script. +# +# Copyright (c) 2006, Sangoma Technologies Inc. +# +# 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. +# ---------------------------------------------------------------------------- +# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option +# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode +# Jul 20, 2007 2.5 David Yat Sin silent option +# Jun 13, 2007 Yuan Shen SS7 support +# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major +# changes to script. +# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl +# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong +# context +# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards +# Oct 13, 2006 David Yat Sin Added --opermode and --law option +# Oct 12, 2006 David Yat Sin Initial version +# ============================================================================ + +system('clear'); +print "\n###################################################################"; +print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; +print "\n# v2.7 #"; +print "\n# Sangoma Technologies Inc. #"; +print "\n# Copyright(c) 2007. #"; +print "\n###################################################################\n\n"; + +use strict; +#use warnings; +#use diagnostics; +use Card; +use A10x; +use A10u; +use A20x; +use A50x; + +my $FALSE = 1; +my $TRUE = 0; +my $zaptelprobe=' '; + +my $etc_dir=""; +my $module_list=""; +my $module_load=""; +my $module_unload=""; +my $os_type_name=""; + + +my $os_type_list=`sysctl -a |grep ostype`; +if ($os_type_list =~ m/Linux/){ + $os_type_name="Linux"; + $etc_dir="/etc"; + $module_load="modprobe"; + $module_unload="modprobe -r"; + $module_list="modprobe -l"; +}elsif ($os_type_list =~ m/FreeBSD/){ + $os_type_name="FreeBSD"; + $etc_dir="/usr/local/etc"; + $module_load="kldload"; + $module_unload="kldunload"; + $module_list="kldstat"; +}else{ + print("Failed to determine OS type\n"); + print("Exiting...\n"); + exit(1); +} + + +my $startup_string=""; +my $zaptel_conf=""; +my $zapata_conf=""; +my $bri_conf=""; +my $devnum=1; +my $current_zap_span=1; +my $current_tdmapi_span=1; +my $current_bri_span=1; +my $current_zap_channel=1; +my $num_analog_devices=0; +my $num_analog_devices_total=0; +my $num_bri_devices=0; +my $num_bri_devices_total=0; +my $num_digital_devices=0; +my $num_digital_devices_total=0; +my $num_ss7_config=0; +my $num_zaptel_config=0; +my $line_media=''; +my $max_chans=0; +my $ss7_tdmvoicechans=''; +my $ss7_array_length=0; + +my $device_has_hwec=$FALSE; +my $device_has_normal_clock=$FALSE; +my @device_normal_clocks=("0"); + +my $is_tdm_api=$FALSE; + +my $def_femedia=''; +my $def_feframe=''; +my $def_feclock=''; +my $def_bri_option=''; +my $def_signalling=''; +my $def_switchtype=''; +my $def_zapata_context=''; +my $def_zapata_group=''; +my $def_te_ref_clock=''; +my $def_tdmv_dchan=0; +my $def_bri_group=''; +my $def_felcode=''; +my $def_feframe=''; +my $def_te_sig_mode=''; + +my $def_hw_dtmf="YES"; + +my $silent_femedia="T1"; +my $silent_feframe="ESF"; +my $silent_feframe_e1="CRC4"; + +my $silent_felcode="B8ZS"; + +my $silent_feclock="NORMAL"; +my $silent_signalling="PRI CPE"; +my $silent_switchtype="National"; +my $silent_zapata_context="from-pstn"; +my $silent_zapata_group="0"; +my $silent_te_sig_mode='CCS'; + +my $def_bri_country="europe"; +my $def_bri_operator="etsi"; +my $def_bri_conn_type="Point to point"; + +my $is_trixbox = $FALSE; +my $silent = $FALSE; +my $config_zaptel = $TRUE; +my $config_zapata = $TRUE; +my $is_smg = $FALSE; + +my $tdm_api_span_num=0; +my $zaptel_installed=$FALSE; +my $modprobe_list=`$module_list`; + + +read_args(); +check_zaptel(); +my $current_dir=`pwd`; +chomp($current_dir); +my $cfg_dir='tmp_cfg'; +my $curdircfg="$current_dir"."/"."$cfg_dir"; + +unless ( -d $curdircfg ) { + $curdircfg = "mkdir " . $curdircfg; + system ($curdircfg); +} + + +my $debug_info_file="$current_dir/$cfg_dir/debug_info"; +my @hwprobe=`wanrouter hwprobe verbose`; + +my $wanpipe_conf_dir="$etc_dir/wanpipe"; +my $asterisk_conf_dir="$etc_dir/asterisk"; + +my $wanrouter_rc_template="$current_dir/templates/rc.template"; + +my $zaptel_conf_template="$current_dir/templates/zaptel.conf"; +my $zaptel_conf_file="$current_dir/$cfg_dir/zaptel.conf"; +my $zaptel_conf_file_t="$etc_dir/zaptel.conf"; + +my $zapata_conf_template="$current_dir/templates/zapata.conf"; +my $zapata_conf_file="$current_dir/$cfg_dir/zapata.conf"; +my $zapata_conf_file_t="$asterisk_conf_dir/zapata.conf"; + +my $bri_conf_template="$current_dir/templates/smg_bri.conf"; +my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; +my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; + +my $date=`date +%F`; +chomp($date); +my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; + +prepare_files(); +config_t1e1(); +config_bri(); +config_analog(); +summary(); +apply_changes(); +config_boot(); +config_ztcfg_start(); +config_smg_ctrl_start(); +clean_files(); +print "\n\n"; + + +#######################################FUNCTIONS################################################## + +sub config_boot{ + my $script_name="wanrouter"; + my $current_run_level=3; + my $zaptel_start_level=9; + my $zaptel_stop_level=92; + my $wanrouter_start_level=8; + my $wanrouter_stop_level=93; + my $command=''; + my $rc_dir=$etc_dir; + + my $res=`cat $etc_dir/inittab |grep id`; + if ($res =~ /id:(\d+):initdefault/){ + $current_run_level=$1; +# print "Current boot level is $current_run_level\n"; + } else { + print "Warning: Failed to determine init boot level, assuming 3\n"; + $current_run_level=3; + } + + + print "\nWanrouter boot scripts configuration...\n\n"; + print "Removing existing $script_name boot scripts..."; + $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; + if(system($command) == 0){ + print "OK\n"; + } else { + print "Not installed\n"; + } + if($num_ss7_config!=0){ + $script_name="smgss7_ctrl"; + } + + print ("Would you like $script_name to start on system boot?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + #examine system bootstrap files + $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$rc_dir; + } else { + $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$etc_dir."/rc.d"; + } else { + print "Failed to locate boostrap directory\n"; + print "wanrouter boot scripts will not be installed\n"; + return; + } + } + + if($zaptel_installed==$TRUE){ + print "Verifying Zaptel boot scripts..."; + #find zaptel start scripts + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; + $res=`$command`; + if ($res =~ /.*S(\d+)zaptel/){ + $zaptel_start_level=$1; + print "Enabled (level:$zaptel_start_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_start_level"; + } + } else { + print "Not installed\n"; + $zaptel_start_level=0; + } + + #find zaptel stop scripts + print "Verifying Zaptel shutdown scripts..."; + $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find ".$rc_dir."/rc6.d/*zaptel"; + $res=`$command`; + if ($res =~ /.*K(\d+)zaptel/){ + $zaptel_stop_level=$1; + print "Enabled (level:$zaptel_stop_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; + } + } else { + print "Not installed\n"; + $zaptel_stop_level=0; + } + if ($zaptel_start_level != 0){ + $wanrouter_start_level=$zaptel_start_level-1; + } + if ($zaptel_stop_level != 0){ + $wanrouter_stop_level=$zaptel_stop_level+1; + } + } + my $wanrouter_start_script=''; + if($wanrouter_start_level < 10){ + $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; + } else { + $wanrouter_start_script="S".$wanrouter_start_level.$script_name; + } + my $wanrouter_stop_script=''; + if($wanrouter_stop_level < 10){ + $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; + } else { + $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; + } + + $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; + if(system($command) !=0){ + $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; + if(system($command) !=0){ + print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; + print "$script_name boot scripts not installed\n"; + return; + } + } + print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; + if(system($command) !=0){ + print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; + print "$script_name start scripts not installed\n"; + return; + } + } + + print "Enabling wanrouter shutdown scripts ...(level:$wanrouter_stop_level)\n"; + @run_levels= ("0","1","6"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; + if(system($command) !=0){ + print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; + print "$script_name stop scripts not installed\n"; + return; + } + } + } + +} + + +sub config_ztcfg_start{ + if ($num_zaptel_config ==0){ + return; + } + my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) != 0){ + #Zaptel init scripts not installed, prompt for wanpipe_zaptel_start_script + print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + exec_command("cp -f $current_dir/templates/zaptel_start_script $wanpipe_conf_dir/scripts/start"); + } + } +} + +sub config_smg_ctrl_start{ + if($num_bri_devices == 0){ + return; + } + print ("Would you like smg_ctrl to start on wanrouter start?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite + my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; + } else { + $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; + } + if (system($command) == 0){ + print "smgbri start script installed successfully"; + } else { + print "failed to install smgbri start script"; + } + } +} + +sub check_zaptel{ + if ($modprobe_list =~ /zaptel.ko/){ + $zaptel_installed=$TRUE; + } +} + +sub apply_changes{ + my $asterisk_command=''; + my $bri_command=''; + my $asterisk_restart=$FALSE; + my $res=''; + + system('clear'); + + if($silent==$TRUE){ + $res="Stop now"; + }elsif($is_tdm_api==$TRUE){ + print "\n Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", + "Do not save cfg: Exit", + ""); + }else{ + print "\nZaptel and Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", + "Save cfg: Restart Asterisk & Wanpipe when convenient", + "Save cfg: Stop Asterisk & Wanpipe now", + "Save cfg: Stop Asterisk & Wanpipe when convenient", + "Do not save cfg: Exit", + ""); + } + + + if ($res =~ m/Exit/){ + print "No changes made to your configuration files\n"; + exit 0; + } + if ($res =~ m/now/){ + $asterisk_command='stop now'; + } else { + $asterisk_command='stop when convenient'; + } + + if ($res =~ m/Restart/){ + $asterisk_restart=$TRUE; + } else { + $asterisk_restart=$FALSE; + } + + if ($is_trixbox==$TRUE){ + exec_command("amportal stop"); + unload_zap_modules(); + } elsif ($is_tdm_api==$FALSE ){ + if (`(pidof asterisk)` != 0 ){ + print "\nStopping Asterisk...\n"; + exec_command("asterisk -rx \"$asterisk_command\""); + sleep 2; + while (`(pidof asterisk)` != 0 ){ + if ($asterisk_command eq "stop now"){ + print "Failed to stop asterisk using command: \'$asterisk_command\' \n"; + my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes"); + my $res=&prompt_user_list(@options,""); + + if ( $res =~ m/Force Stop/){ + execute_command("kill -KILL \$(pidof asterisk)"); + } elsif ( $res =~ m/Exit/ ){ + exit(1); + } else { + print "Waiting for asterisk to stop...\n"; + sleep 5; + exec_command("asterisk -rx \"$asterisk_command\""); + } + } else { + #stop when convenient option was selected + print "Waiting for asterisk to stop...\n"; + sleep 3; + } + } + + + + + + }else { + print "\nAsterisk is not running...\n"; + } + + } + + if($num_bri_devices != 0){ + exec_command("/usr/sbin/smg_ctrl stop"); + } + + print "\nStopping Wanpipe...\n"; + exec_command("wanrouter stop all"); + + if ($zaptel_installed==$TRUE){ + if($is_tdm_api==$FALSE){ + print "\nUnloading Zaptel modules...\n"; + unload_zap_modules(); + } + } + + print "\nRemoving old configuration files...\n"; + + exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); + + gen_wanrouter_rc(); + + print "\nCopying new Wanpipe configuration files...\n"; + copy_config_files(); + if($num_bri_devices != 0){ + print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; + exec_command("cp -f $bri_conf_file $bri_conf_file_t"); + } + + if ($zaptel_installed==$TRUE){ + if($config_zaptel==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; + exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); + } + } + } + + if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ + print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; + exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); + } + + if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ + print "\nStarting Wanpipe...\n"; + exec_command("wanrouter start"); + + if($num_bri_devices != 0){ + print "Loading SMG BRI...\n"; + sleep 2; + exec_command("/usr/sbin/smg_ctrl start"); + } + +# if ( ! -e "/$wanpipe_conf_dir/scripts/start" & $is_trixbox==$FALSE && $is_smg==$FALSE ){ + if ($num_zaptel_config != 0){ + print "Loading Zaptel...\n"; + sleep 2; + exec_command("ztcfg -v"); +# print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); +# if (&prompt_user_list("YES","NO","") eq 'YES'){ +# exec_command("cp -f $wanpipe_conf_dir/samples/wanpipe_zaptel_start $wanpipe_conf_dir/scripts/start"); +# } + } + if ($is_trixbox==$TRUE){ + print "\nStarting Amportal...\n"; + exec_command("amportal start"); + sleep 2; + }elsif($config_zapata==$TRUE){ + print "\nStarting Asterisk...\n"; + exec_command("asterisk"); + sleep 2; + + print "\nListing Asterisk channels...\n\n"; + exec_command("asterisk -rx \"zap show channels\""); + print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; + }else{ + } + } + print "\nWanrouter start complete...\n"; +} + + + +sub save_debug_info{ + my $version=`wanrouter version`; + chomp($version); + + my $uname=`uname -a`; + chomp($uname); + + my $issue=''; + + if ($os_type_list =~ m/Linux/){ + $issue=`cat $etc_dir/issue`; + chomp($issue); + } + + my $debug_info="\n"; + $debug_info.="===============================================================\n"; + $debug_info.=" SANGOMA DEBUG INFO FILE \n"; + $debug_info.=" Generated on $date \n"; + $debug_info.="===============================================================\n"; + + $debug_info.="\n\nwanrouter hwprobe\n"; + $debug_info.="@hwprobe\n"; + $debug_info.="\nwanrouter version\n"; + $debug_info.="$version\n"; + $debug_info.="\nKernel \"uname -a\"\n"; + $debug_info.="$uname\n"; + if ($os_type_list =~ m/Linux/){ + $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; + $debug_info.="$issue\n"; + } + $debug_info.="EOF\n"; + + open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; + print FH $debug_info; + close (FH); + exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); +} + + + + + + + + + +sub get_zapata_context{ + my ($card_model,$card_port)=@_; + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("Select dialplan context for A%s on port %s\n", $card_model, $card_port); + my $res = &prompt_user_list(@options,$def_zapata_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_zapata_context); + } + + $context=$res_context; + }elsif($res eq $def_zapata_context){ + $context=$def_zapata_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + $context=$silent_zapata_context; + } + $def_zapata_context=$context; + return $context; +} + +sub gen_wanrouter_rc{ + #update wanpipe startup sequence + my $rcfile=""; + if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { + open (FH,"$wanrouter_rc_template"); + } + while () { + $rcfile .= $_; + } + close (FH); + open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); + $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; + print FH $rcfile; + close (FH); +} + +sub prepare_files{ + + if ($is_trixbox==$TRUE){ + $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; + $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; + $zapata_conf_file_t="$asterisk_conf_dir/zapata-auto.conf"; + } + + if ($silent==$FALSE){ + if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ + print "Would you like to generate $zapata_conf_file_t\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $config_zapata = $FALSE; + } + } + } + +#remove temp files + exec_command("rm -f $current_dir/$cfg_dir/*"); + +#backup existing configuration files + exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); + exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); + +} + +sub clean_files{ + exec_command("rm -rf $current_dir/$cfg_dir"); +} + + +sub write_zapata_conf{ + my $zp_file=""; + open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + + $zp_file.=$zapata_conf; + + open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; + print FH $zp_file; + close(FH); +} + +sub copy_config_files{ + my @wanpipe_files = split / /, $startup_string; + exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc $wanpipe_conf_dir"); + foreach my $wanpipe_file (@wanpipe_files) { + exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf $wanpipe_conf_dir"); + } +} + + + + + + + + + + + + +sub unload_zap_modules{ + my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); + foreach my $module (@modules_list) { + if ($modprobe_list =~ m/$module/){ + exec_command("$module_unload -r $module"); + } + } +} + +sub write_zaptel_conf{ + my $zp_file=""; + open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + $zp_file=$zp_file.$zaptel_conf; + open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; + print FH $zp_file; + close(FH); +} + +sub summary{ + if($devnum==1){ + system('clear'); + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); + exit 0; + }else{ + if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ + write_zaptel_conf(); + } + if ($num_bri_devices != 0 ){ + write_bri_conf(); + } + if ($config_zapata==$TRUE){ + write_zapata_conf(); + } + save_debug_info(); + system('clear'); + my $file_list = 1; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); + print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); + print(" $num_bri_devices_total ISDN BRI card(s) detected, $num_bri_devices configured\n"); + + print "\nConfigurator has created the following files:\n"; + print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; + $file_list++; + + if ($num_bri_devices != 0){ + print "\t$file_list. sangoma_brid config file $wanpipe_conf_dir/smg_bri\n"; + $file_list++; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; + } + + if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ + print "\n\nYour original configuration files will be saved to:\n"; + $file_list=1; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. $zaptel_conf_file_t.bak \n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. $zapata_conf_file_t.bak \n\n"; + } + + print "\nYour configuration has been saved in $debug_tarball.\n"; + print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } +} + + +sub exec_command{ + my @command = @_; + if (system(@command) != 0 ){ + print "Error executing command:\n@command\n\n"; + } + return $?; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "def=\"$defaultValue\": "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $defaultValue = @list[$#list]; + + my $i; + my $valid = 0; + for $i (0..$#list-1) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + my $list_sz = $#list; + print "[1-$list_sz"; + if ( ! $defaultValue eq ''){ + print ", ENTER=\'$defaultValue\']:"; + }else{ + print "]:"; + } + $| = 1; + $_ = ; + chomp; + if ( $_ eq '' & ! $defaultValue eq ''){ + print "\n"; + return $defaultValue; + } + + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $list_sz) { + print "\nError: Invalid option, input a value between 1 and $list_sz \n"; + } else { + print "\n"; + return @list[$1-1] ; + } + } else { + print "\nError: Invalid option, input an integer\n"; + } + } +} + +sub read_args { + my $arg_num; + foreach $arg_num (0 .. $#ARGV) { + $_ = $ARGV[$arg_num]; + if( /^--trixbox$/){ + $is_trixbox=$TRUE; + }elsif ( /^--tdm_api/){ + $is_tdm_api=$TRUE; + }elsif ( /^--smg$/){ + $is_smg=$TRUE; + }elsif ( /^--silent$/){ + $silent=$TRUE; + }elsif ( /^--no-zapata$/){ + $config_zapata=$FALSE; + }elsif ( /^--no-zaptel$/){ + $config_zaptel=$FALSE; + }elsif ( $_ =~ /--fe_media=(\w+)/){ + $silent_femedia=$1; + if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ + printf("Invalid value for fe_media, should be T1/E1\n"); + exit(1); + } + }elsif ( $_ =~ /--fe_frame=(\w+)/){ + $silent_feframe=$1; + if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ + printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); + exit(1); + } + }elsif ( $_ =~ /--fe_clock=(\w+)/){ + $silent_feclock=$1; + if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ + printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); + exit(1); + } + }elsif ( $_ =~ /--signalling=(\w+)/){ + my $tmp_signalling=$1; + if ($tmp_signalling eq 'em'){ + $silent_signalling="E & M"; + }elsif ($tmp_signalling eq 'em_w'){ + $silent_signalling="E & M Wink"; + }elsif ($tmp_signalling eq 'pri_cpe'){ + $silent_signalling="PRI CPE"; + }elsif ($tmp_signalling eq 'pri_net'){ + $silent_signalling="PRI NET"; + }elsif ($tmp_signalling eq 'fxs_ls'){ + $silent_signalling="FXS - Loop Start"; + }elsif ($tmp_signalling eq 'fxs_gs'){ + $silent_signalling="FXS - Ground Start"; + }elsif ($tmp_signalling eq 'fxs_ks'){ + $silent_signalling="FXS - Kewl Start"; + }elsif ($tmp_signalling eq 'fxo_ls'){ + $silent_signalling="FXO - Loop Start"; + }elsif ($tmp_signalling eq 'fxo_gs'){ + $silent_signalling="FXO - Ground Start"; + }elsif ($tmp_signalling eq 'fxo_ks'){ + $silent_signalling="FXO - Kewl Start"; + }else{ + printf("Invalid option for --signalling, options are\n"); + printf("\t pri_cpe/pri_net/em/em_w\n"); + printf("\t em/em_w\n"); + printf("\t fxo_ls/fxo_gs/fxo_ks\n"); + printf("\t fxs_ls/fxs_gs/fxs_ks\n"); + exit(1); + } + }elsif ( $_ =~ /--conf_dir=(.*)/){ + $etc_dir=$1; + if (! -d $etc_dir){ + printf("Error: directory $1 does not exist\n"); + exit(1); + } + } + } + + if ($is_trixbox==$TRUE){ + print "\nGenerating configuration files for Trixbox\n"; + } + if ($is_smg==$TRUE){ + print "\nGenerating configuration files for SS7\n"; + } + if ($is_tdm_api==$TRUE){ + $config_zapata = $FALSE; + } + +} + +#------------------------------BRI FUNCTIONS------------------------------------# +sub get_bri_country { + $def_bri_country = "europe"; + return $def_bri_country; +} + +sub get_bri_group{ + my $group; + my $res_group=&prompt_user("\nInput the group for this port\n",$def_bri_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ + print "Invalid group, input an integer greater than 0\n"; + $res_group=&prompt_user("Input the group for this port",$def_bri_group); + } + $group=$res_group; + $def_bri_group=$group; + return $def_bri_group; +} + + +sub get_bri_operator { +#warning returning ETSI + $def_bri_operator = "etsi"; + return $def_bri_operator; + + + + my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", + "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", + "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); + + my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); + + my $res = &prompt_user_list(@options,$def_switchtype); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_operator=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + +sub write_bri_conf{ + my $bri_file=""; + open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; + while () { + $bri_file .= $_; +} + close (FH); + $bri_file=$bri_file.$bri_conf; + open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; + print FH $bri_file; + close(FH); +} + + +sub get_bri_conn_type{ + my $conn_type; + + my @options = ( "Point to multipoint", "Point to point"); + my @options_val = ("point_to_multipoint", "point_to_point"); + + my $res = &prompt_user_list(@options,$def_bri_conn_type); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_conn_type=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid BRI connection type\n"; + exit 1; +} + + + + +sub config_bri{ + if($is_smg!=$TRUE){ + return; + } + my $a50x; + system('clear'); + print "------------------------------------\n"; + print "Configuring ISDN BRI cards [A500]\n"; + print "------------------------------------\n"; + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ + $skip_card=$FALSE; + if ($1 eq '500'){ + my $card = eval {new Card(); } or die ($@); + + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->span_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + + my $hwec=0; + if($6 gt 0){ + $hwec=1; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + + if ($card->card_model eq '500'){ + $num_bri_devices_total++; + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + + if($is_trixbox==$FALSE){ +select_bri_option: + print "\nWould you like to configure A$1 port $5 on slot:$3 bus:$4\n"; + my @options=("YES", "NO", "Exit"); + $def_bri_option=&prompt_user_list(@options,$def_bri_option); + if($def_bri_option eq 'YES'){ + $skip_card=$FALSE; + $bri_conf.="\n;Sangoma A$1 port $5 [slot:$3 bus:$4 span:$devnum]"; + }elsif($def_bri_option eq 'NO'){ + $skip_card=$TRUE; + }else{ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } else { + goto select_bri_option; + } + } + } + if ($skip_card==$FALSE){ +# print "A$1 port:$5 configured on slot:$3 bus:$4 span:$devnum\n"; +# prompt_user("Press any key to continue"); + + $startup_string.="wanpipe$devnum "; + $a50x = eval {new A50x(); } or die ($@); + $a50x->card($card); + $a50x->fe_line($5); + $devnum++; + $num_bri_devices++; + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + $a50x->gen_wanpipe_conf(); + }else{ + print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; + prompt_user("Press any key to continue"); + } + + } + } + }elsif ( $dev =~ /(\d+):NT/ & $skip_card==$FALSE){ + printf("\nConfiguring port %d as NT\n", $a50x->fe_line()); + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $bri_pos=$current_bri_span; + + $current_bri_span=$current_bri_span+1; + my $conn_type=get_bri_conn_type(); + my $group=get_bri_group(); + my $country=get_bri_country(); + + my $operator=get_bri_operator(); + $bri_conf.=$a50x->gen_bri_conf($bri_pos, "bri_nt" , $group, $country, $operator, $conn_type); + }elsif ( $dev =~ /(\d+):TE/ & $skip_card==$FALSE){ + printf("\nConfiguring port %d as TE\n", $a50x->fe_line()); + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $bri_pos=$current_bri_span; + + $current_bri_span=$current_bri_span+1; + my $conn_type=get_bri_conn_type(); + my $group=get_bri_group(); + my $country=get_bri_country(); + + my $operator=get_bri_operator(); + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); + } + } + prompt_user("Press any key to continue"); + if($num_bri_devices_total!=0){ + print("\nISBN BRI card configuration complete\n\n"); + prompt_user("Press any key to continue"); + } +} + + + + + +#------------------------------T1/E1 FUNCTIONS------------------------------------# + +sub get_te_ref_clock{ + my @list_normal_clocks=@_; + my @f_list_normal_clocks; + my $f_port; + foreach my $port (@list_normal_clocks) { + if ($port eq '0'){ + $f_port = "Free run"; +} else { + $f_port = "Port ".$port; +} + push(@f_list_normal_clocks, $f_port); +} + + my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); + my $i; + + for $i (0..$#f_list_normal_clocks){ + if ( $res eq @f_list_normal_clocks[$i] ){ + return @list_normal_clocks[$i]; +} +} + + print "Internal error: Invalid reference clock\n"; + exit 1; + +} + + +sub prompt_user_hw_dchan{ + my ($card_model, $port, $port_femedia) = @_; + my $res_dchan=''; + my $dchan; + + printf("Hardware HDLC can be performed on the data channel.\n"); +prompt_hw_dchan: + my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); + while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ + print "Invalid channel, input an integer (0 for unused).\n"; + $res_dchan=&prompt_user("Select the data channel","0"); + } + if ( $res_dchan < 0){ + printf("Error: channel cannot have negative value\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ( $port_femedia eq 'T1' && $res_dchan > 24){ + printf("Error: only 24 channels available on T1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + }elsif ($port_femedia eq 'E1' && $res_dchan > 31){ + printf("Error: only 31 channels available on E1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ($res_dchan == 0){ + printf("HW HDLC channel not used\n"); + }else{ + printf("HW HDLC channel set to:%d\n", $res_dchan); + } + return $res_dchan; +} + + + +sub get_zapata_group{ + my ($card_model,$card_port,$context)=@_; + my $group=''; + if($is_trixbox==$TRUE){ + if($context eq "from-zaptel"){ + $group=0; + return $group; + }elsif($context eq "from-internal"){ + $group=1; + return $group; + }else{ + print "Internal error:invalid group for Trixbox\n"; + } + }else{ + if($context eq "from-pstn"){ + $group=0; + }elsif($context eq "from-internal"){ + $group=1; + }else{ + my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)){ + print "Invalid group, input an integer.\n"; + $res_group=&prompt_user("Input the group for this port",$def_zapata_group); + } + $group=$res_group; + $def_zapata_group=$group; + } + } + + return $group; +} + + + +sub prompt_hw_dtmf { + print("Would you like to enable hardware DTMF detection?\n"); + my @options = ("YES","NO"); + $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); + return $def_hw_dtmf; + +} + +sub get_pri_switchtype { + my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); + my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); + my $res = &prompt_user_list(@options,$def_switchtype); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_switchtype=@options[$i]; + return @options_val[$i]; +} +} + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + + +sub gen_ss7_voicechans{ + my @ss7_array = @_; + my $T1CHANS = pop(@ss7_array); + my $count = @ss7_array; + my $output =''; + my $chan_in = 1; + my $chan_de = 0; + my $flag = 0; + my $i = 0; + my $j = 0; + + while($i < $count){ + $j = $i + 1; + if ($ss7_array[$i] > 2 && $i == 0){ + $chan_de = $ss7_array[$i] - 1; + $output .= "1-$chan_de"; + $flag = 1; + }elsif ($ss7_array[$i] == 2 && $i == 0){ + $output .= "1"; + $flag = 1; + } + + if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ + goto Incrementing; + }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ + goto Incrementing; + } + + if ($i < ($count-1)){ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < ($ss7_array[$j]-1)){ + $chan_de = $ss7_array[$j] - 1; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$chan_in"; + }else{ + $output .= "$chan_in"; + $flag = 1; + } + } + }else{ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < $T1CHANS){ + $chan_de = $T1CHANS; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$T1CHANS"; + }else{ + $output .= "$T1CHANS"; + $flag = 1; + } + } + } + +Incrementing: + $i++; + } + return $output; +} + +sub prompt_user_ss7_chans{ + my @ss7_string = @_; + my $def_ss7_group_chan = ''; + + my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + +CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ + print("ERROR: Invalid channel number, input an integer only.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); +} + if ($line_media eq 'T1'){ + while ($ss7_group_chan>24 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 24 channels in T1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +}elsif ($line_media eq 'E1'){ + while ($ss7_group_chan>31 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 31 channels in E1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +} + return $ss7_group_chan; +} + + + + + + +sub config_t1e1{ + system('clear'); + print "---------------------------------------------\n"; + print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; + print "---------------------------------------------\n"; + + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + + if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ + #do not count analog devices + $num_digital_devices_total++; + } + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->span_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + + my $hwec=0; + if ( $dev =~ /HWEC=(\d+)/){ + if($1 gt 0){ + $hwec=1; + } + } + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + my $port=$6; + if ($6 eq 'PRI') { + $port=$5; + } + + if ( $card->card_model eq '101' | + $card->card_model eq '102' | + $card->card_model eq '104' | + $card->card_model eq '108' ){ + system('clear'); + if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ + print "A$1 detected on slot:$3 bus:$4\n"; + $device_has_normal_clock=$FALSE; + @device_normal_clocks = ("0"); + } + system('clear'); + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; + print "$msg"; + print "-----------------------------------------------------------\n"; + my $fe_media = ''; + if ($silent==$TRUE){ + $fe_media = $silent_femedia; + } else { + printf ("\nSelect media type for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + my @options = ("T1", "E1", "Unused","Exit"); + $fe_media = prompt_user_list( @options, $def_femedia); + } + + if ( $fe_media eq 'Exit'){ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } + }elsif ( $fe_media eq 'Unused'){ + $def_femedia=$fe_media; + my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; + print "$msg"; + prompt_user("Press any key to continue"); + }else{ + if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ + $device_has_hwec=$TRUE; + } + + $def_femedia=$fe_media; + $startup_string.="wanpipe$devnum "; + my $a10x; + + if ($1 !~ m/104/ && $2 !~ m/SH/) { + $a10x = eval {new A10u(); } or die ($@); + $a10x->card($card); + if ($5 eq "A") { + $a10x->fe_line("1"); + } else { + $a10x->fe_line("2"); + } + } else { + $a10x = eval {new A10x(); } or die ($@); + if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + $a10x->card($card); + $a10x->fe_line($6); + } + + $card->first_chan($current_zap_channel); + $a10x->fe_media($fe_media); + if ( $fe_media eq 'T1' ){ + $current_zap_channel+=24; + $max_chans = 24; + $line_media = 'T1'; + + $def_te_sig_mode=''; + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s.\n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe, + $port); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("B8ZS", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("ESF", "D4"); + $def_feframe= &prompt_user_list(@options, $def_feframe); + } + + + } else { + $def_felcode=$silent_felcode; + } + + + }else{ #fe_media = E1 + $current_zap_channel+=31; + $max_chans = 31; + $line_media = 'E1'; + + + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("HDB3", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("CRC4", "NCRC4","UNFRAMED"); + $def_feframe = &prompt_user_list(@options, $def_feframe); + +# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); +# my @options = ("CCS - Clear channel signalling ", "CAS"); +# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); + + } + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + } else { + $def_te_sig_mode="CAS"; + } + + + } else { + $def_felcode=$silent_felcode; + } + + + } + $a10x->fe_lcode($def_felcode); + $a10x->fe_frame($def_feframe); + $a10x->te_sig_mode($def_te_sig_mode); + if($silent==$FALSE){ + my @options = ("NORMAL", "MASTER"); + printf ("Select clock for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_feclock=&prompt_user_list(@options, $def_feclock); + } else { + $def_feclock=$silent_feclock; + } + + $a10x->fe_clock($def_feclock); + if ( $def_feclock eq 'NORMAL') { + $device_has_normal_clock=$TRUE; + push(@device_normal_clocks, $a10x->fe_line); + } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ + printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", + $card->card_model, + $port, + $card->pci_slot, + $card->pci_bus); + printf(" Free run: Use internal oscillator on card [default] \n"); + printf(" Port N: Sync with clock from port N \n\n"); + + printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); + $a10x->te_ref_clock($def_te_ref_clock); + } + + my @options=""; + if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ +# if ($is_smg==$TRUE && ($zaptelprobe =~ /zaptel.ko/)){ + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_smg==$TRUE && $zaptel_installed==$FALSE){ +# } elsif ($is_smg==$TRUE && ($zaptelprobe !~ /zaptel.ko/)){ + @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_tdm_api==$TRUE){ + $def_signalling="TDM API"; + } else { + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); + } + if ($silent==$FALSE){ + if( $is_tdm_api == $FALSE){ + printf ("Select signalling type for %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_signalling=&prompt_user_list(@options,$def_signalling); + } + } else { + $def_signalling=$silent_signalling; + } + $a10x->signalling($def_signalling); + + + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + } + + my $ss7_chan; + my $ss7_group_start; + my $ss7_group_end; + my @ss7_chan_array; + my @ss7_sorted; + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_option(1); + print("Choose an option below to configure SS7 signalling channels:\n"); + my @options =("Configure consecutive signalling channels(e.g #1-#16)", + "Configure separate signalling channels(e.g #1,#10)"); + my $res = &prompt_user_list(@options, ""); + if ( $res eq 'Configure separate signalling channels(e.g #1,#10)'){ + goto SS7CHAN; + while (1){ + print("\nAny other SS7 signalling channel to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7CHAN: + $ss7_chan = prompt_user_ss7_chans('Specify the time slot for SS7 signalling(24 for T1? 16 for E1?)'); + push(@ss7_chan_array, $ss7_chan); + $ss7_array_length = @ss7_chan_array; + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + }else{ + goto SS7GROUP; + while(1){ + print("\nAny other SS7 consecutive signalling channels to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7GROUP: + $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); + $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); + if ($ss7_group_start > $ss7_group_end){ + print("The starting channel number is bigger than the ending one!\n"); + goto SS7GROUP; + } + my $i = 0; + for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ + push(@ss7_chan_array, $i); + my @remove_duplicate; + @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); + $ss7_array_length = @ss7_chan_array; + + if ($ss7_array_length > $max_chans){ + print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); + + @ss7_chan_array = (); + goto SS7GROUP; + } + } + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + } + +ENDSS7CONFIG: + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); + my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); + $ss7_tdmvoicechans = $ss7_voicechans; + + if ($ss7_voicechans =~ m/(\d+)/){ + $a10x->ss7_tdminterface($1); + } + + $a10x->ss7_tdmchan($ss7_voicechans); + $num_ss7_config++; + }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ + $a10x->ss7_option(2); + $num_ss7_config++; + }elsif ($a10x->signalling eq 'TDM API'){ + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); + } + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + }else{ + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + } + + + if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ + if ($silent==$FALSE && $config_zapata==$TRUE){ + printf ("Select switchtype for %s on port %s \n", $card->card_model, $port); + $a10x->pri_switchtype(get_pri_switchtype()); + } else { + $a10x->pri_switchtype($silent_switchtype); + } + } + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_subinterface(1); + $a10x->gen_wanpipe_ss7_subinterfaces(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(2); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + my $ss7_element; + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + + $a10x->gen_wanpipe_conf(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + }else{ + $a10x->gen_wanpipe_conf(); + } + + if ($is_smg==$TRUE && $config_zapata==$FALSE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' + | $a10x->signalling eq 'No Signaling (Voice Only)')){ + } + $zaptel_conf.=$a10x->gen_zaptel_conf(); + }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ + + $zaptel_conf.=$a10x->gen_zaptel_conf(); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + } + }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + $zaptel_conf.=$a10x->gen_zaptel_conf(); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + }elsif ($is_tdm_api == $FALSE){ + $zaptel_conf.=$a10x->gen_zaptel_conf(); + } + $devnum++; + $num_digital_devices++; + my $msg ="\n\nPort ".$port." on A".$card->card_model." configuration complete...\n"; + print "$msg"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + } + } + + } + } + if($num_digital_devices_total!=0){ + print("\nT1/E1 card configuration complete.\n"); + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } +# close SCR; +} + + +#------------------------------ANALOG FUNCTIONS------------------------------------# + + +sub config_analog{ + my $a20x; + system('clear'); + print "------------------------------------\n"; + print "Configuring analog cards [A200/A400]\n"; + print "------------------------------------\n"; + + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ + $skip_card=$FALSE; + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->span_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + my $hwec=$7; + if ($hwec==0){ + $card->hwec_mode('NO'); + } + else{ + $card->hwec_mode('YES'); + } + if ($card->card_model eq '200' | $card->card_model eq '400'){ + $num_analog_devices_total++; + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + if($is_trixbox==$FALSE){ + print "\nWould you like to configure A$1 on slot:$3 bus:$4\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $skip_card=$TRUE; + } + } + if ($skip_card==$FALSE){ + print "A$1 configured on slot:$3 bus:$4 span:$devnum\n"; + prompt_user("Press any key to continue"); + $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; + $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; + $startup_string.="wanpipe$devnum "; + + $a20x = eval {new A20x(); } or die ($@); + $a20x->card($card); + $card->first_chan($current_zap_channel); + $current_zap_channel+=24; + my $i; + $devnum++; + $num_analog_devices++; + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + $a20x->gen_wanpipe_conf(); + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + } + }else{ + print "A$1 on slot:$3 bus:$4 not configured\n"; + prompt_user("Press any key to continue"); + } + } + }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-internal"); + $a20x->card->zap_group("1"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); + }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-zaptel"); + $a20x->card->zap_group("0"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); + } + } + if($num_analog_devices_total!=0){ + print("\nAnalog card configuration complete\n\n"); + prompt_user("Press any key to continue"); + } + +} + diff --git a/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.32 b/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.32 new file mode 100755 index 0000000..073845d --- /dev/null +++ b/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.32 @@ -0,0 +1,1977 @@ +#!/usr/bin/perl +# config-zaptel.pl +# Sangoma Zaptel/TDM API/SMG Configuration Script. +# +# Copyright (c) 2006, Sangoma Technologies Inc. +# +# 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. +# ---------------------------------------------------------------------------- +# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option +# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode +# Jul 20, 2007 2.5 David Yat Sin silent option +# Jun 13, 2007 Yuan Shen SS7 support +# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major +# changes to script. +# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl +# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong +# context +# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards +# Oct 13, 2006 David Yat Sin Added --opermode and --law option +# Oct 12, 2006 David Yat Sin Initial version +# ============================================================================ + +system('clear'); +print "\n###################################################################"; +print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; +print "\n# v2.7 #"; +print "\n# Sangoma Technologies Inc. #"; +print "\n# Copyright(c) 2007. #"; +print "\n###################################################################\n\n"; + +use strict; +#use warnings; +#use diagnostics; +use Card; +use A10x; +use A10u; +use A20x; +use A50x; + +my $FALSE = 1; +my $TRUE = 0; +my $zaptelprobe=' '; + +my $etc_dir=""; +my $module_list=""; +my $module_load=""; +my $module_unload=""; +my $os_type_name=""; + + +my $os_type_list=`sysctl -a |grep ostype`; +if ($os_type_list =~ m/Linux/){ + $os_type_name="Linux"; + $etc_dir="/etc"; + $module_load="modprobe"; + $module_unload="modprobe -r"; + $module_list="modprobe -l"; +}elsif ($os_type_list =~ m/FreeBSD/){ + $os_type_name="FreeBSD"; + $etc_dir="/usr/local/etc"; + $module_load="kldload"; + $module_unload="kldunload"; + $module_list="kldstat"; +}else{ + print("Failed to determine OS type\n"); + print("Exiting...\n"); + exit(1); +} + + +my $startup_string=""; +my $cfg_string=""; +my $first_cfg=1; +my $zaptel_conf=""; +my $zapata_conf=""; +my $bri_conf=""; +my $devnum=1; +my $current_zap_span=1; +my $current_tdmapi_span=1; +my $current_bri_span=1; +my $current_zap_channel=1; +my $num_analog_devices=0; +my $num_analog_devices_total=0; +my $num_bri_devices=0; +my $num_bri_devices_total=0; +my $num_digital_devices=0; +my $num_digital_devices_total=0; +my $num_ss7_config=0; +my $num_zaptel_config=0; +my $line_media=''; +my $max_chans=0; +my $ss7_tdmvoicechans=''; +my $ss7_array_length=0; + +my $device_has_hwec=$FALSE; +my $device_has_normal_clock=$FALSE; +my @device_normal_clocks=("0"); + +my $is_tdm_api=$FALSE; + +my $def_femedia=''; +my $def_feframe=''; +my $def_feclock=''; +my $def_bri_option=''; +my $def_signalling=''; +my $def_switchtype=''; +my $def_zapata_context=''; +my $def_zapata_group=''; +my $def_te_ref_clock=''; +my $def_tdmv_dchan=0; +my $def_bri_group=''; +my $def_felcode=''; +my $def_feframe=''; +my $def_te_sig_mode=''; + +my $def_hw_dtmf="YES"; + +my $silent_femedia="T1"; +my $silent_feframe="ESF"; +my $silent_feframe_e1="CRC4"; + +my $silent_felcode="B8ZS"; + +my $silent_feclock="NORMAL"; +my $silent_signalling="PRI CPE"; +my $silent_switchtype="National"; +my $silent_zapata_context="from-pstn"; +my $silent_zapata_group="0"; +my $silent_te_sig_mode='CCS'; + +my $def_bri_country="europe"; +my $def_bri_operator="etsi"; +my $def_bri_conn_type="Point to point"; + +my $is_trixbox = $FALSE; +my $silent = $FALSE; +my $config_zaptel = $TRUE; +my $config_zapata = $TRUE; +my $is_smg = $FALSE; + +my $tdm_api_span_num=0; +my $zaptel_installed=$FALSE; +my $modprobe_list=`$module_list`; + + +read_args(); +check_zaptel(); +my $current_dir=`pwd`; +chomp($current_dir); +my $cfg_dir='tmp_cfg'; +my $curdircfg="$current_dir"."/"."$cfg_dir"; + +unless ( -d $curdircfg ) { + $curdircfg = "mkdir " . $curdircfg; + system ($curdircfg); +} + + +my $debug_info_file="$current_dir/$cfg_dir/debug_info"; +my @hwprobe=`wanrouter hwprobe verbose`; + +my $wanpipe_conf_dir="$etc_dir/wanpipe"; +my $asterisk_conf_dir="$etc_dir/asterisk"; + +my $wanrouter_rc_template="$current_dir/templates/wanrouter.rc.template"; + +my $zaptel_conf_template="$current_dir/templates/zaptel.conf"; +my $zaptel_conf_file="$current_dir/$cfg_dir/zaptel.conf"; +my $zaptel_conf_file_t="$etc_dir/zaptel.conf"; + +my $zapata_conf_template="$current_dir/templates/zapata.conf"; +my $zapata_conf_file="$current_dir/$cfg_dir/zapata.conf"; +my $zapata_conf_file_t="$asterisk_conf_dir/zapata.conf"; + +my $bri_conf_template="$current_dir/templates/smg_bri.conf"; +my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; +my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; + +my $date=`date +%F`; +chomp($date); +my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; + +prepare_files(); +config_t1e1(); +config_bri(); +config_analog(); +summary(); +apply_changes(); +config_boot(); +config_ztcfg_start(); +config_smg_ctrl_start(); +clean_files(); +print "\n\n"; + + +#######################################FUNCTIONS################################################## + +sub config_boot{ + my $script_name="wanrouter"; + my $current_run_level=3; + my $zaptel_start_level=9; + my $zaptel_stop_level=92; + my $wanrouter_start_level=8; + my $wanrouter_stop_level=93; + my $command=''; + my $rc_dir=$etc_dir; + + if ($os_type_list =~ m/FreeBSD/){ + return; + } + my $res=`cat $etc_dir/inittab |grep id`; + if ($res =~ /id:(\d+):initdefault/){ + $current_run_level=$1; +# print "Current boot level is $current_run_level\n"; + } else { + print "Warning: Failed to determine init boot level, assuming 3\n"; + $current_run_level=3; + } + + + print "\nWanrouter boot scripts configuration...\n\n"; + print "Removing existing $script_name boot scripts..."; + $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; + if(system($command) == 0){ + print "OK\n"; + } else { + print "Not installed\n"; + } + if($num_ss7_config!=0){ + $script_name="smgss7_init_ctrl"; + } + + print ("Would you like $script_name to start on system boot?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + #examine system bootstrap files + $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$rc_dir; + } else { + $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$etc_dir."/rc.d"; + } else { + print "Failed to locate boostrap directory\n"; + print "wanrouter boot scripts will not be installed\n"; + return; + } + } + + if($zaptel_installed==$TRUE){ + print "Verifying Zaptel boot scripts..."; + #find zaptel start scripts + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; + $res=`$command`; + if ($res =~ /.*S(\d+)zaptel/){ + $zaptel_start_level=$1; + print "Enabled (level:$zaptel_start_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_start_level"; + } + } else { + print "Not installed\n"; + $zaptel_start_level=0; + } + + #find zaptel stop scripts + print "Verifying Zaptel shutdown scripts..."; + $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find ".$rc_dir."/rc6.d/*zaptel"; + $res=`$command`; + if ($res =~ /.*K(\d+)zaptel/){ + $zaptel_stop_level=$1; + print "Enabled (level:$zaptel_stop_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; + } + } else { + print "Not installed\n"; + $zaptel_stop_level=0; + } + if ($zaptel_start_level != 0){ + $wanrouter_start_level=$zaptel_start_level-1; + } + if ($zaptel_stop_level != 0){ + $wanrouter_stop_level=$zaptel_stop_level+1; + } + } + my $wanrouter_start_script=''; + if($wanrouter_start_level < 10){ + $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; + } else { + $wanrouter_start_script="S".$wanrouter_start_level.$script_name; + } + my $wanrouter_stop_script=''; + if($wanrouter_stop_level < 10){ + $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; + } else { + $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; + } + + $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; + if(system($command) !=0){ + $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; + if(system($command) !=0){ + print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; + print "$script_name boot scripts not installed\n"; + return; + } + } + print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; + if(system($command) !=0){ + print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; + print "$script_name start scripts not installed\n"; + return; + } + } + + print "Enabling $script_name shutdown scripts ...(level:$wanrouter_stop_level)\n"; + @run_levels= ("0","1","6"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; + if(system($command) !=0){ + print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; + print "$script_name stop scripts not installed\n"; + return; + } + } + } + +} + + +sub config_ztcfg_start{ + if ($num_zaptel_config ==0){ + return; + } + my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) != 0){ + #Zaptel init scripts not installed, prompt for wanpipe_zaptel_start_script + print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + exec_command("cp -f $current_dir/templates/zaptel_cfg_script $wanpipe_conf_dir/scripts/start"); + } + } +} + +sub config_smg_ctrl_start{ + if($num_bri_devices == 0){ + return; + } + print ("Would you like smg_ctrl to start on wanrouter start?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite + my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; + } else { + $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; + } + if (system($command) == 0){ + print "smgbri start script installed successfully"; + } else { + print "failed to install smgbri start script"; + } + } +} + +sub check_zaptel{ + if ($modprobe_list =~ /zaptel.ko/){ + $zaptel_installed=$TRUE; + } +} + +sub apply_changes{ + my $asterisk_command=''; + my $bri_command=''; + my $asterisk_restart=$FALSE; + my $res=''; + + system('clear'); + + if($silent==$TRUE){ + $res="Stop now"; + }elsif($is_tdm_api==$TRUE){ + print "\n Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", + "Do not save cfg: Exit", + ""); + }else{ + print "\nZaptel and Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", + "Save cfg: Restart Asterisk & Wanpipe when convenient", + "Save cfg: Stop Asterisk & Wanpipe now", + "Save cfg: Stop Asterisk & Wanpipe when convenient", + "Do not save cfg: Exit", + ""); + } + + + if ($res =~ m/Exit/){ + print "No changes made to your configuration files\n"; + exit 0; + } + if ($res =~ m/now/){ + $asterisk_command='stop now'; + } else { + $asterisk_command='stop when convenient'; + } + + if ($res =~ m/Restart/){ + $asterisk_restart=$TRUE; + } else { + $asterisk_restart=$FALSE; + } + + if ($is_trixbox==$TRUE){ + exec_command("amportal stop"); + unload_zap_modules(); + } elsif ($is_tdm_api==$FALSE ){ + if (`(pidof asterisk)` != 0 ){ + print "\nStopping Asterisk...\n"; + exec_command("asterisk -rx \"$asterisk_command\""); + sleep 2; + while (`(pidof asterisk)` != 0 ){ + if ($asterisk_command eq "stop now"){ + print "Failed to stop asterisk using command: \'$asterisk_command\' \n"; + my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes"); + my $res=&prompt_user_list(@options,""); + + if ( $res =~ m/Force Stop/){ + execute_command("kill -KILL \$(pidof asterisk)"); + } elsif ( $res =~ m/Exit/ ){ + exit(1); + } else { + print "Waiting for asterisk to stop...\n"; + sleep 5; + exec_command("asterisk -rx \"$asterisk_command\""); + } + } else { + #stop when convenient option was selected + print "Waiting for asterisk to stop...\n"; + sleep 3; + } + } + + + + + + }else { + print "\nAsterisk is not running...\n"; + } + + } + + if($num_bri_devices != 0){ + exec_command("/usr/sbin/smg_ctrl stop"); + } + + print "\nStopping Wanpipe...\n"; + exec_command("wanrouter stop all"); + + if ($zaptel_installed==$TRUE){ + if($is_tdm_api==$FALSE){ + print "\nUnloading Zaptel modules...\n"; + unload_zap_modules(); + } + } + + print "\nRemoving old configuration files...\n"; + + exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); + + gen_wanrouter_rc(); + + print "\nCopying new Wanpipe configuration files...\n"; + copy_config_files(); + if($num_bri_devices != 0){ + print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; + exec_command("cp -f $bri_conf_file $bri_conf_file_t"); + } + + if ($zaptel_installed==$TRUE){ + if($config_zaptel==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; + exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); + } + } + } + + if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ + print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; + exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); + } + + if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ + print "\nStarting Wanpipe...\n"; + exec_command("wanrouter start"); + + if($num_bri_devices != 0){ + print "Loading SMG BRI...\n"; + sleep 2; + exec_command("/usr/sbin/smg_ctrl start"); + } + +# if ( ! -e "/$wanpipe_conf_dir/scripts/start" & $is_trixbox==$FALSE && $is_smg==$FALSE ){ + if ($num_zaptel_config != 0){ + print "Loading Zaptel...\n"; + sleep 2; + exec_command("ztcfg -v"); +# print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); +# if (&prompt_user_list("YES","NO","") eq 'YES'){ +# exec_command("cp -f $wanpipe_conf_dir/samples/wanpipe_zaptel_start $wanpipe_conf_dir/scripts/start"); +# } + } + if ($is_trixbox==$TRUE){ + print "\nStarting Amportal...\n"; + exec_command("amportal start"); + sleep 2; + }elsif($config_zapata==$TRUE){ + print "\nStarting Asterisk...\n"; + exec_command("asterisk"); + sleep 2; + + print "\nListing Asterisk channels...\n\n"; + exec_command("asterisk -rx \"zap show channels\""); + print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; + }else{ + } + } + print "\nWanrouter start complete...\n"; +} + + + +sub save_debug_info{ + my $version=`wanrouter version`; + chomp($version); + + my $uname=`uname -a`; + chomp($uname); + + my $issue=''; + + if ($os_type_list =~ m/Linux/){ + $issue=`cat $etc_dir/issue`; + chomp($issue); + } + + my $debug_info="\n"; + $debug_info.="===============================================================\n"; + $debug_info.=" SANGOMA DEBUG INFO FILE \n"; + $debug_info.=" Generated on $date \n"; + $debug_info.="===============================================================\n"; + + $debug_info.="\n\nwanrouter hwprobe\n"; + $debug_info.="@hwprobe\n"; + $debug_info.="\nwanrouter version\n"; + $debug_info.="$version\n"; + $debug_info.="\nKernel \"uname -a\"\n"; + $debug_info.="$uname\n"; + if ($os_type_list =~ m/Linux/){ + $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; + $debug_info.="$issue\n"; + } + $debug_info.="EOF\n"; + + open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; + print FH $debug_info; + close (FH); + exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); +} + + + + + + + + + +sub get_zapata_context{ + my ($card_model,$card_port)=@_; + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("Select dialplan context for A%s on port %s\n", $card_model, $card_port); + my $res = &prompt_user_list(@options,$def_zapata_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_zapata_context); + } + + $context=$res_context; + }elsif($res eq $def_zapata_context){ + $context=$def_zapata_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + $context=$silent_zapata_context; + } + $def_zapata_context=$context; + return $context; +} + +sub gen_wanrouter_rc{ + #update wanpipe startup sequence + my $rcfile=""; + if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { + open (FH,"$wanrouter_rc_template"); + } + while () { + $rcfile .= $_; + } + close (FH); + open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); + $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; + print FH $rcfile; + close (FH); +} + +sub prepare_files{ + + if ($is_trixbox==$TRUE){ + $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; + $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; + $zapata_conf_file_t="$asterisk_conf_dir/zapata-auto.conf"; + } + + if ($silent==$FALSE){ + if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ + print "Would you like to generate $zapata_conf_file_t\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $config_zapata = $FALSE; + } + } + } + +#remove temp files + my $tmp_cfg_dir="$current_dir"."/"."$cfg_dir"; + if ( -d "$current_dir"."/"."$cfg_dir") { + exec_command("rm -f $current_dir/$cfg_dir/*"); + } +#backup existing configuration files + if ( -f $zaptel_conf_file_t ) { + exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); + } + + if ( -f $zapata_conf_file_t ) { + exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); + } +} + +sub clean_files{ + exec_command("rm -rf $current_dir/$cfg_dir"); +} + + +sub write_zapata_conf{ + my $zp_file=""; + open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + + $zp_file.=$zapata_conf; + + open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; + print FH $zp_file; + close(FH); +} + +sub copy_config_files{ + my @wanpipe_files = split / /, $cfg_string; + exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc $wanpipe_conf_dir"); + foreach my $wanpipe_file (@wanpipe_files) { + exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf $wanpipe_conf_dir"); + } +} + +sub unload_zap_modules{ + my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); + foreach my $module (@modules_list) { + if ($modprobe_list =~ m/$module/){ + exec_command("$module_unload $module"); + } + } +} + +sub write_zaptel_conf{ + my $zp_file=""; + open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + $zp_file=$zp_file.$zaptel_conf; + open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; + print FH $zp_file; + close(FH); +} + +sub summary{ + if($devnum==1){ + system('clear'); + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); + exit 0; + }else{ + if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ + write_zaptel_conf(); + } + if ($num_bri_devices != 0 ){ + write_bri_conf(); + } + if ($config_zapata==$TRUE){ + write_zapata_conf(); + } + save_debug_info(); + system('clear'); + my $file_list = 1; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); + print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); + print(" $num_bri_devices_total ISDN BRI card(s) detected, $num_bri_devices configured\n"); + + print "\nConfigurator has created the following files:\n"; + print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; + $file_list++; + + if ($num_bri_devices != 0){ + print "\t$file_list. sangoma_brid config file $wanpipe_conf_dir/smg_bri\n"; + $file_list++; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; + } + + if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ + print "\n\nYour original configuration files will be saved to:\n"; + $file_list=1; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. $zaptel_conf_file_t.bak \n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. $zapata_conf_file_t.bak \n\n"; + } + + print "\nYour configuration has been saved in $debug_tarball.\n"; + print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } +} + + +sub exec_command{ + my @command = @_; + if (system(@command) != 0 ){ + print "Error executing command:\n@command\n\n"; + } + return $?; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "def=\"$defaultValue\": "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $defaultValue = @list[$#list]; + + my $i; + my $valid = 0; + for $i (0..$#list-1) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + my $list_sz = $#list; + print "[1-$list_sz"; + if ( ! $defaultValue eq ''){ + print ", ENTER=\'$defaultValue\']:"; + }else{ + print "]:"; + } + $| = 1; + $_ = ; + chomp; + if ( $_ eq '' & ! $defaultValue eq ''){ + print "\n"; + return $defaultValue; + } + + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $list_sz) { + print "\nError: Invalid option, input a value between 1 and $list_sz \n"; + } else { + print "\n"; + return @list[$1-1] ; + } + } else { + print "\nError: Invalid option, input an integer\n"; + } + } +} + +sub read_args { + my $arg_num; + foreach $arg_num (0 .. $#ARGV) { + $_ = $ARGV[$arg_num]; + if( /^--trixbox$/){ + $is_trixbox=$TRUE; + }elsif ( /^--tdm_api/){ + $is_tdm_api=$TRUE; + }elsif ( /^--smg$/){ + $is_smg=$TRUE; + }elsif ( /^--silent$/){ + $silent=$TRUE; + }elsif ( /^--no-zapata$/){ + $config_zapata=$FALSE; + }elsif ( /^--no-zaptel$/){ + $config_zaptel=$FALSE; + }elsif ( $_ =~ /--fe_media=(\w+)/){ + $silent_femedia=$1; + if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ + printf("Invalid value for fe_media, should be T1/E1\n"); + exit(1); + } + }elsif ( $_ =~ /--fe_frame=(\w+)/){ + $silent_feframe=$1; + if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ + printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); + exit(1); + } + }elsif ( $_ =~ /--fe_clock=(\w+)/){ + $silent_feclock=$1; + if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ + printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); + exit(1); + } + }elsif ( $_ =~ /--signalling=(\w+)/){ + my $tmp_signalling=$1; + if ($tmp_signalling eq 'em'){ + $silent_signalling="E & M"; + }elsif ($tmp_signalling eq 'em_w'){ + $silent_signalling="E & M Wink"; + }elsif ($tmp_signalling eq 'pri_cpe'){ + $silent_signalling="PRI CPE"; + }elsif ($tmp_signalling eq 'pri_net'){ + $silent_signalling="PRI NET"; + }elsif ($tmp_signalling eq 'fxs_ls'){ + $silent_signalling="FXS - Loop Start"; + }elsif ($tmp_signalling eq 'fxs_gs'){ + $silent_signalling="FXS - Ground Start"; + }elsif ($tmp_signalling eq 'fxs_ks'){ + $silent_signalling="FXS - Kewl Start"; + }elsif ($tmp_signalling eq 'fxo_ls'){ + $silent_signalling="FXO - Loop Start"; + }elsif ($tmp_signalling eq 'fxo_gs'){ + $silent_signalling="FXO - Ground Start"; + }elsif ($tmp_signalling eq 'fxo_ks'){ + $silent_signalling="FXO - Kewl Start"; + }else{ + printf("Invalid option for --signalling, options are\n"); + printf("\t pri_cpe/pri_net/em/em_w\n"); + printf("\t em/em_w\n"); + printf("\t fxo_ls/fxo_gs/fxo_ks\n"); + printf("\t fxs_ls/fxs_gs/fxs_ks\n"); + exit(1); + } + }elsif ( $_ =~ /--conf_dir=(.*)/){ + $etc_dir=$1; + if (! -d $etc_dir){ + printf("Error: directory $1 does not exist\n"); + exit(1); + } + } + } + + if ($is_trixbox==$TRUE){ + print "\nGenerating configuration files for Trixbox\n"; + } + if ($is_smg==$TRUE){ + print "\nGenerating configuration files for SS7\n"; + } + if ($is_tdm_api==$TRUE){ + $config_zapata = $FALSE; + } + +} + +#------------------------------BRI FUNCTIONS------------------------------------# +sub get_bri_country { + $def_bri_country = "europe"; + return $def_bri_country; +} + +sub get_bri_group{ + my $group; + my $res_group=&prompt_user("\nInput the group for this port\n",$def_bri_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ + print "Invalid group, input an integer greater than 0\n"; + $res_group=&prompt_user("Input the group for this port",$def_bri_group); + } + $group=$res_group; + $def_bri_group=$group; + return $def_bri_group; +} + + +sub get_bri_operator { +#warning returning ETSI + $def_bri_operator = "etsi"; + return $def_bri_operator; + + + + my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", + "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", + "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); + + my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); + + my $res = &prompt_user_list(@options,$def_switchtype); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_operator=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + +sub write_bri_conf{ + my $bri_file=""; + open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; + while () { + $bri_file .= $_; +} + close (FH); + $bri_file=$bri_file.$bri_conf; + open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; + print FH $bri_file; + close(FH); +} + + +sub get_bri_conn_type{ + my $conn_type; + + my @options = ( "Point to multipoint", "Point to point"); + my @options_val = ("point_to_multipoint", "point_to_point"); + + my $res = &prompt_user_list(@options,$def_bri_conn_type); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_conn_type=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid BRI connection type\n"; + exit 1; +} + + + + +sub config_bri{ + if($is_smg!=$TRUE){ + return; + } + my $a50x; + if (!$first_cfg) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring ISDN BRI cards [A500]\n"; + print "------------------------------------\n"; + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ + $skip_card=$FALSE; + if ($1 eq '500'){ + my $card = eval {new Card(); } or die ($@); + + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->span_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + + my $hwec=0; + if($6 gt 0){ + $hwec=1; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + + if ($card->card_model eq '500'){ + $num_bri_devices_total++; + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + + if($is_trixbox==$FALSE){ +select_bri_option: + print "\nWould you like to configure A$1 port $5 on slot:$3 bus:$4\n"; + my @options=("YES", "NO", "Exit"); + $def_bri_option=&prompt_user_list(@options,$def_bri_option); + if($def_bri_option eq 'YES'){ + $skip_card=$FALSE; + $bri_conf.="\n;Sangoma A$1 port $5 [slot:$3 bus:$4 span:$devnum]"; + }elsif($def_bri_option eq 'NO'){ + $skip_card=$TRUE; + }else{ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } else { + goto select_bri_option; + } + } + } + if ($skip_card==$FALSE){ +# print "A$1 port:$5 configured on slot:$3 bus:$4 span:$devnum\n"; +# prompt_user("Press any key to continue"); + + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + $a50x = eval {new A50x(); } or die ($@); + $a50x->card($card); + $a50x->fe_line($5); + $devnum++; + $num_bri_devices++; + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + $a50x->gen_wanpipe_conf(); + }else{ + print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; + prompt_user("Press any key to continue"); + } + + } + } + }elsif ( $dev =~ /(\d+):NT/ & $skip_card==$FALSE){ + printf("\nConfiguring port %d as NT\n", $a50x->fe_line()); + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $bri_pos=$current_bri_span; + + $current_bri_span=$current_bri_span+1; + my $conn_type=get_bri_conn_type(); + my $group=get_bri_group(); + my $country=get_bri_country(); + + my $operator=get_bri_operator(); + $bri_conf.=$a50x->gen_bri_conf($bri_pos, "bri_nt" , $group, $country, $operator, $conn_type); + }elsif ( $dev =~ /(\d+):TE/ & $skip_card==$FALSE){ + printf("\nConfiguring port %d as TE\n", $a50x->fe_line()); + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $bri_pos=$current_bri_span; + + $current_bri_span=$current_bri_span+1; + my $conn_type=get_bri_conn_type(); + my $group=get_bri_group(); + my $country=get_bri_country(); + + my $operator=get_bri_operator(); + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); + } + } +# prompt_user("Press any key to continue"); + if($num_bri_devices_total!=0){ + print("\nISBN BRI card configuration complete\n\n"); + prompt_user("Press any key to continue"); + } else { + print("\nNo Sangoma ISDN BRI cards detected\n\n"); + prompt_user("Press any key to continue"); + + } +} + + + + + +#------------------------------T1/E1 FUNCTIONS------------------------------------# + +sub get_te_ref_clock{ + my @list_normal_clocks=@_; + my @f_list_normal_clocks; + my $f_port; + foreach my $port (@list_normal_clocks) { + if ($port eq '0'){ + $f_port = "Free run"; +} else { + $f_port = "Port ".$port; +} + push(@f_list_normal_clocks, $f_port); +} + + my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); + my $i; + + for $i (0..$#f_list_normal_clocks){ + if ( $res eq @f_list_normal_clocks[$i] ){ + return @list_normal_clocks[$i]; +} +} + + print "Internal error: Invalid reference clock\n"; + exit 1; + +} + + +sub prompt_user_hw_dchan{ + my ($card_model, $port, $port_femedia) = @_; + my $res_dchan=''; + my $dchan; + + printf("Hardware HDLC can be performed on the data channel.\n"); +prompt_hw_dchan: + my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); + while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ + print "Invalid channel, input an integer (0 for unused).\n"; + $res_dchan=&prompt_user("Select the data channel","0"); + } + if ( $res_dchan < 0){ + printf("Error: channel cannot have negative value\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ( $port_femedia eq 'T1' && $res_dchan > 24){ + printf("Error: only 24 channels available on T1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + }elsif ($port_femedia eq 'E1' && $res_dchan > 31){ + printf("Error: only 31 channels available on E1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ($res_dchan == 0){ + printf("HW HDLC channel not used\n"); + }else{ + printf("HW HDLC channel set to:%d\n", $res_dchan); + } + return $res_dchan; +} + + + +sub get_zapata_group{ + my ($card_model,$card_port,$context)=@_; + my $group=''; + if($is_trixbox==$TRUE){ + if($context eq "from-zaptel"){ + $group=0; + return $group; + }elsif($context eq "from-internal"){ + $group=1; + return $group; + }else{ + print "Internal error:invalid group for Trixbox\n"; + } + }else{ + if($context eq "from-pstn"){ + $group=0; + }elsif($context eq "from-internal"){ + $group=1; + }else{ + my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)){ + print "Invalid group, input an integer.\n"; + $res_group=&prompt_user("Input the group for this port",$def_zapata_group); + } + $group=$res_group; + $def_zapata_group=$group; + } + } + + return $group; +} + + + +sub prompt_hw_dtmf { + print("Would you like to enable hardware DTMF detection?\n"); + my @options = ("YES","NO"); + $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); + return $def_hw_dtmf; + +} + +sub get_pri_switchtype { + my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); + my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); + my $res = &prompt_user_list(@options,$def_switchtype); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_switchtype=@options[$i]; + return @options_val[$i]; +} +} + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + + +sub gen_ss7_voicechans{ + my @ss7_array = @_; + my $T1CHANS = pop(@ss7_array); + my $count = @ss7_array; + my $output =''; + my $chan_in = 1; + my $chan_de = 0; + my $flag = 0; + my $i = 0; + my $j = 0; + + while($i < $count){ + $j = $i + 1; + if ($ss7_array[$i] > 2 && $i == 0){ + $chan_de = $ss7_array[$i] - 1; + $output .= "1-$chan_de"; + $flag = 1; + }elsif ($ss7_array[$i] == 2 && $i == 0){ + $output .= "1"; + $flag = 1; + } + + if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ + goto Incrementing; + }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ + goto Incrementing; + } + + if ($i < ($count-1)){ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < ($ss7_array[$j]-1)){ + $chan_de = $ss7_array[$j] - 1; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$chan_in"; + }else{ + $output .= "$chan_in"; + $flag = 1; + } + } + }else{ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < $T1CHANS){ + $chan_de = $T1CHANS; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$T1CHANS"; + }else{ + $output .= "$T1CHANS"; + $flag = 1; + } + } + } + +Incrementing: + $i++; + } + return $output; +} + +sub prompt_user_ss7_chans{ + my @ss7_string = @_; + my $def_ss7_group_chan = ''; + + my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + +CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ + print("ERROR: Invalid channel number, input an integer only.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); +} + if ($line_media eq 'T1'){ + while ($ss7_group_chan>24 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 24 channels in T1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +}elsif ($line_media eq 'E1'){ + while ($ss7_group_chan>31 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 31 channels in E1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +} + return $ss7_group_chan; +} + + + + + + +sub config_t1e1{ + if (!$first_cfg) { + system('clear'); + } + print "---------------------------------------------\n"; + print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; + print "---------------------------------------------\n"; + + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + + if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ + #do not count analog devices + $num_digital_devices_total++; + } + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->span_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + + my $hwec=0; + if ( $dev =~ /HWEC=(\d+)/){ + if($1 gt 0){ + $hwec=1; + } + } + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + my $port=$6; + if ($6 eq 'PRI') { + $port=$5; + } + + if ( $card->card_model eq '101' | + $card->card_model eq '102' | + $card->card_model eq '104' | + $card->card_model eq '108' ){ + if (!$first_cfg) { + system('clear'); + } + if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ + print "A$1 detected on slot:$3 bus:$4\n"; + $device_has_normal_clock=$FALSE; + @device_normal_clocks = ("0"); + } + if (!$first_cfg) { + system('clear'); + } + $first_cfg=0; + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; + print "$msg"; + print "-----------------------------------------------------------\n"; + my $fe_media = ''; + if ($silent==$TRUE){ + $fe_media = $silent_femedia; + } else { + printf ("\nSelect media type for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + my @options = ("T1", "E1", "Unused","Exit"); + $fe_media = prompt_user_list( @options, $def_femedia); + } + + if ( $fe_media eq 'Exit'){ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } + }elsif ( $fe_media eq 'Unused'){ + $def_femedia=$fe_media; + my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; + print "$msg"; + prompt_user("Press any key to continue"); + }else{ + if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ + $device_has_hwec=$TRUE; + } + + $def_femedia=$fe_media; + $cfg_string.="wanpipe$devnum "; + my $a10x; + + if ($1 !~ m/104/ && $2 !~ m/SH/) { + $a10x = eval {new A10u(); } or die ($@); + $a10x->card($card); + if ($5 eq "A") { + $a10x->fe_line("1"); + } else { + $a10x->fe_line("2"); + } + } else { + $a10x = eval {new A10x(); } or die ($@); + if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + $a10x->card($card); + $a10x->fe_line($6); + } + + $card->first_chan($current_zap_channel); + $a10x->fe_media($fe_media); + if ( $fe_media eq 'T1' ){ + $max_chans = 24; + $line_media = 'T1'; + + $def_te_sig_mode=''; + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + + + if ($silent==$FALSE){ + printf ("Configuring port %s on AFT-A%s as: %s, coding:%s, framing:%s.\n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe, + $port); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("B8ZS", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("ESF", "D4"); + $def_feframe= &prompt_user_list(@options, $def_feframe); + } + + + } else { + $def_felcode=$silent_felcode; + } + + + }else{ #fe_media = E1 + $max_chans = 31; + $line_media = 'E1'; + + + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("HDB3", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("CRC4", "NCRC4","UNFRAMED"); + $def_feframe = &prompt_user_list(@options, $def_feframe); + +# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); +# my @options = ("CCS - Clear channel signalling ", "CAS"); +# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); + + } + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + } else { + $def_te_sig_mode="CAS"; + } + + + } else { + $def_felcode=$silent_felcode; + } + + + } + $a10x->fe_lcode($def_felcode); + $a10x->fe_frame($def_feframe); + if($silent==$FALSE){ + my @options = ("NORMAL", "MASTER"); + printf ("Select clock for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_feclock=&prompt_user_list(@options, $def_feclock); + } else { + $def_feclock=$silent_feclock; + } + + $a10x->fe_clock($def_feclock); + if ( $def_feclock eq 'NORMAL') { + $device_has_normal_clock=$TRUE; + push(@device_normal_clocks, $a10x->fe_line); + } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ + printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", + $card->card_model, + $port, + $card->pci_slot, + $card->pci_bus); + printf(" Free run: Use internal oscillator on card [default] \n"); + printf(" Port N: Sync with clock from port N \n\n"); + + printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); + $a10x->te_ref_clock($def_te_ref_clock); + } + + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + } + + + + my @options=""; + if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_smg==$TRUE && $zaptel_installed==$FALSE){ + @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_tdm_api==$TRUE){ + $def_signalling="TDM API"; + } else { + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); + } + if ($silent==$FALSE){ + if( $is_tdm_api == $FALSE){ + printf ("Select signalling type for %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_signalling=&prompt_user_list(@options,$def_signalling); + } + } else { + $def_signalling=$silent_signalling; + } + $a10x->signalling($def_signalling); + + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + + } else { + $def_te_sig_mode="CAS"; + } + $a10x->te_sig_mode($def_te_sig_mode); + + my $ss7_chan; + my $ss7_group_start; + my $ss7_group_end; + my @ss7_chan_array; + my @ss7_sorted; + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_option(1); + print("Choose an option below to configure SS7 signalling channels:\n"); + my @options =("Configure individual signalling channels(e.g #1,#10)", + "Configure consecutive signalling channels(e.g #1-#16)"); + my $res = &prompt_user_list(@options, ""); + if ( $res eq 'Configure individual signalling channels(e.g #1,#10)'){ + goto SS7CHAN; + while (1){ + print("\nAny other SS7 signalling channel to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7CHAN: + $ss7_chan = prompt_user_ss7_chans('Specify the time slot for SS7 signalling(24 for T1? 16 for E1?)'); + push(@ss7_chan_array, $ss7_chan); + $ss7_array_length = @ss7_chan_array; + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + }else{ + goto SS7GROUP; + while(1){ + print("\nAny other SS7 consecutive signalling channels to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7GROUP: + $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); + $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); + if ($ss7_group_start > $ss7_group_end){ + print("The starting channel number is bigger than the ending one!\n"); + goto SS7GROUP; + } + my $i = 0; + for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ + push(@ss7_chan_array, $i); + my @remove_duplicate; + @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); + $ss7_array_length = @ss7_chan_array; + + if ($ss7_array_length > $max_chans){ + print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); + + @ss7_chan_array = (); + goto SS7GROUP; + } + } + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + } + +ENDSS7CONFIG: + + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); + my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); + $ss7_tdmvoicechans = $ss7_voicechans; + + if ($ss7_voicechans =~ m/(\d+)/){ + $a10x->ss7_tdminterface($1); + } + + $a10x->ss7_tdmchan($ss7_voicechans); + + $num_ss7_config++; + }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ + $a10x->ss7_option(2); + $num_ss7_config++; + $startup_string.="wanpipe$devnum "; + }elsif ($a10x->signalling eq 'TDM API'){ + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); + } + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + $startup_string.="wanpipe$devnum "; + }else{ + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + $startup_string.="wanpipe$devnum "; + $current_zap_channel+=$max_chans; + } + + + + if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ + if ($silent==$FALSE && $config_zapata==$TRUE){ + printf ("Select switchtype for %s on port %s \n", $card->card_model, $port); + $a10x->pri_switchtype(get_pri_switchtype()); + } else { + $a10x->pri_switchtype($silent_switchtype); + } + } + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_subinterface(1); + $a10x->gen_wanpipe_ss7_subinterfaces(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(2); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + my $ss7_element; + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + + $a10x->gen_wanpipe_conf(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + }else{ + $a10x->gen_wanpipe_conf(); + } + + if ($is_smg==$TRUE && $config_zapata==$FALSE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' + | $a10x->signalling eq 'No Signaling (Voice Only)')){ + $zaptel_conf.=$a10x->gen_zaptel_conf(); + } + }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ + + $zaptel_conf.=$a10x->gen_zaptel_conf(); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + } + }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + $zaptel_conf.=$a10x->gen_zaptel_conf(); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + }elsif ($is_tdm_api == $FALSE){ + $zaptel_conf.=$a10x->gen_zaptel_conf(); + } + $devnum++; + $num_digital_devices++; + my $msg ="\n\nPort ".$port." on A".$card->card_model." configuration complete...\n"; + print "$msg"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + } + + + } + + } + } + if($num_digital_devices_total!=0){ + print("\nT1/E1 card configuration complete.\n"); + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + $first_cfg=0; + } +# close SCR; +} + + +#------------------------------ANALOG FUNCTIONS------------------------------------# + + +sub config_analog{ + my $a20x; + if (!$first_cfg) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring analog cards [A200/A400]\n"; + print "------------------------------------\n"; + + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ + $skip_card=$FALSE; + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->span_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + my $hwec=$7; + if ($hwec==0){ + $card->hwec_mode('NO'); + } + else{ + $card->hwec_mode('YES'); + } + if ($card->card_model eq '200' | $card->card_model eq '400'){ + $num_analog_devices_total++; + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + if($is_trixbox==$FALSE){ + print "\nWould you like to configure A$1 on slot:$3 bus:$4\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $skip_card=$TRUE; + } + } + if ($skip_card==$FALSE){ + + $a20x = eval {new A20x(); } or die ($@); + $a20x->card($card); + $card->first_chan($current_zap_channel); + + if ( $device_has_hwec==$TRUE){ + print "Will this A$1 to synchronize with an existing Sangoma T1/E1 card?\n"; + print "\n WARNING: for hardware and firmware requirements, check:\n"; + print " http://wiki.sangoma.com/t1e1analogfaxing\n"; + + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $a20x->rm_network_sync('NO'); + } else { + $a20x->rm_network_sync('YES'); + } + } + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + } + + + print "A$1 configured on slot:$3 bus:$4 span:$devnum\n"; + prompt_user("Press any key to continue"); + $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; + $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + + $current_zap_channel+=24; + my $i; + $devnum++; + $num_analog_devices++; + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + $a20x->gen_wanpipe_conf(); + + }else{ + print "A$1 on slot:$3 bus:$4 not configured\n"; + prompt_user("Press any key to continue"); + } + } + }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-internal"); + $a20x->card->zap_group("1"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); + }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-zaptel"); + $a20x->card->zap_group("0"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); + } + } + if($num_analog_devices_total!=0){ + print("\nAnalog card configuration complete\n\n"); + prompt_user("Press any key to continue"); + } + +} + diff --git a/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.47 b/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.47 new file mode 100755 index 0000000..0a04668 --- /dev/null +++ b/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.47 @@ -0,0 +1,2237 @@ +#!/usr/bin/perl +# config-zaptel.pl +# Sangoma Zaptel/TDM API/SMG Configuration Script. +# +# Copyright (c) 2006, Sangoma Technologies Inc. +# +# 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. +# ---------------------------------------------------------------------------- +# Jan 02 2008 2.10 David Yat Sin Added option for BRI master clock +# Dec 15 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 +# Nov 29 2007 2.8 David Yat Sin Support for BRI cards on Trixbox +# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option +# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode +# Jul 20, 2007 2.5 David Yat Sin silent option +# Jun 13, 2007 Yuan Shen SS7 support +# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major +# changes to script. +# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl +# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong +# context +# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards +# Oct 13, 2006 David Yat Sin Added --opermode and --law option +# Oct 12, 2006 David Yat Sin Initial version +# ============================================================================ + +system('clear'); +print "\n###################################################################"; +print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; +print "\n# v2.10 #"; +print "\n# Sangoma Technologies Inc. #"; +print "\n# Copyright(c) 2007. #"; +print "\n###################################################################\n\n"; + +use strict; +#use warnings; +#use diagnostics; +use Card; +use A10x; +use A10u; +use A20x; +use A50x; + + +my $FALSE = 1; +my $TRUE = 0; +my $zaptelprobe=' '; + +my $etc_dir=""; +my $include_dir=""; +my $module_list=""; +my $module_load=""; +my $module_unload=""; +my $os_type_name=""; +my $dchan_str="dchan"; + +my $os_type_list=`sysctl -a |grep ostype`; +if ($os_type_list =~ m/Linux/){ + $os_type_name="Linux"; + $etc_dir="/etc"; + $module_load="modprobe"; + $module_unload="modprobe -r"; + $module_list="modprobe -l"; + $include_dir="/usr/include"; +}elsif ($os_type_list =~ m/FreeBSD/){ + $os_type_name="FreeBSD"; + $etc_dir="/usr/local/etc"; + $module_load="kldload"; + $module_unload="kldunload"; + $module_list="kldstat"; +}else{ + print("Failed to determine OS type\n"); + print("Exiting...\n"); + exit(1); +} + + +my $no_boot=$FALSE; +my $startup_string=""; +my $cfg_string=""; +my $first_cfg=1; +my $zaptel_conf=""; +my $zapata_conf=""; +my $bri_conf=""; +my $woomera_conf=""; +my $devnum=1; +my $current_zap_span=1; +my $current_tdmapi_span=1; +#my $current_bri_span=1; +my $current_zap_channel=1; +my $num_analog_devices=0; +my $num_analog_devices_total=0; +my $num_bri_devices=0; +my $num_bri_devices_total=0; +my $num_digital_devices=0; +my $num_digital_devices_total=0; +my $num_ss7_config=0; +my $num_zaptel_config=0; +my $line_media=''; +my $max_chans=0; +my $ss7_tdmvoicechans=''; +my $ss7_array_length=0; + + + +my $device_has_hwec=$FALSE; +my $device_has_normal_clock=$FALSE; +my @device_normal_clocks=("0"); +my @woomera_groups=("0"); +my $bri_device_has_master_clock=$FALSE; + +my $is_tdm_api=$FALSE; + +my $def_femedia=''; +my $def_feframe=''; +my $def_feclock=''; +my $def_bri_option=''; +my $def_signalling=''; +my $def_switchtype=''; +my $def_zapata_context=''; +my $def_woomera_context=''; +my $def_zapata_group=''; +my $def_te_ref_clock=''; +my $def_tdmv_dchan=0; +my $def_bri_group=''; +my $def_felcode=''; +my $def_feframe=''; +my $def_te_sig_mode=''; + +my $def_hw_dtmf="YES"; +my $def_tdm_law=''; + +my $silent_femedia="T1"; +my $silent_feframe="ESF"; +my $silent_feframe_e1="CRC4"; + +my $silent_felcode="B8ZS"; +my $silent_tdm_law="MULAW"; + + +my $silent_feclock="NORMAL"; +my $silent_signalling="PRI CPE"; +my $silent_pri_switchtype="national"; +my $silent_zapata_context="from-pstn"; +my $silent_woomera_context="from-pstn"; +my $silent_zapata_group="0"; +my $silent_te_sig_mode='CCS'; + +my $def_bri_country="europe"; +my $def_bri_operator="etsi"; +my $def_bri_conn_type="Point to multipoint"; + +my $is_trixbox = $FALSE; +my $silent = $FALSE; +my $config_zaptel = $TRUE; +my $config_zapata = $TRUE; +my $is_smg = $FALSE; + +my $tdm_api_span_num=0; +my $zaptel_installed=$FALSE; +my $modprobe_list=`$module_list`; + + +read_args(); +check_zaptel(); +my $current_dir=`pwd`; +chomp($current_dir); +my $cfg_dir='tmp_cfg'; +my $curdircfg="$current_dir"."/"."$cfg_dir"; + +unless ( -d $curdircfg ) { + $curdircfg = "mkdir " . $curdircfg; + system ($curdircfg); +} + + +my $debug_info_file="$current_dir/$cfg_dir/debug_info"; +my @hwprobe=`wanrouter hwprobe verbose`; + +my $wanpipe_conf_dir="$etc_dir/wanpipe"; +my $asterisk_conf_dir="$etc_dir/asterisk"; + +my $wanrouter_rc_template="$current_dir/templates/wanrouter.rc.template"; + +my $zaptel_conf_template="$current_dir/templates/zaptel.conf"; +my $zaptel_conf_file="$current_dir/$cfg_dir/zaptel.conf"; +my $zaptel_conf_file_t="$etc_dir/zaptel.conf"; + +my $zapata_conf_template="$current_dir/templates/zapata.conf"; +my $zapata_conf_file="$current_dir/$cfg_dir/zapata.conf"; +my $zapata_conf_file_t="$asterisk_conf_dir/zapata.conf"; + +my $bri_conf_template="$current_dir/templates/smg_bri.conf"; +my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; +my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; + +my $woomera_conf_template="$current_dir/templates/woomera.conf"; +my $woomera_conf_file="$current_dir/$cfg_dir/woomera.conf"; +my $woomera_conf_file_t="$asterisk_conf_dir/woomera.conf"; + +my $date=`date +%F`; +chomp($date); +my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; + +set_zaptel_hwhdlc(); +prepare_files(); +config_t1e1(); +config_bri(); +config_analog(); +summary(); +apply_changes(); +config_boot(); +config_ztcfg_start(); +config_smg_ctrl_start(); +clean_files(); +print "Sangoma cards configuration complete, exiting...\n\n"; + + +#######################################FUNCTIONS################################################## + + +sub set_zaptel_hwhdlc{ + if ((system("grep hdlc_hard_xmit '$include_dir/zaptel/zaptel.h'>/dev/null 2>/dev/null")==0)){ + $dchan_str="hardhdlc"; + } +} + +sub config_boot{ + if($no_boot==$TRUE){ + return; + } + my $script_name="wanrouter"; + my $current_run_level=3; + my $zaptel_start_level=9; + my $zaptel_stop_level=92; + my $network_start_level=10; + my $wanrouter_start_level=8; + my $wanrouter_stop_level=91; + my $smg_ctrl_start_level=11; + my $command=''; + my $rc_dir=$etc_dir; + + if ($os_type_list =~ m/FreeBSD/){ + return; + } + my $res=`cat $etc_dir/inittab |grep id`; + if ($res =~ /id:(\d+):initdefault/){ + $current_run_level=$1; + print "Current boot level is $current_run_level\n"; + } else { + print "Warning: Failed to determine init boot level, assuming 3\n"; + $current_run_level=3; + } + + + print "\nWanrouter boot scripts configuration...\n\n"; + print "Removing existing $script_name boot scripts..."; + $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; + if(system($command) == 0){ + print "OK\n"; + } else { + print "Not installed\n"; + } + if($num_ss7_config!=0){ + $script_name="smgss7_init_ctrl"; + } + + print ("Would you like $script_name to start on system boot?\n"); + my $res='YES'; + if($silent==$FALSE){ + $res= &prompt_user_list("YES","NO",""); + } + + if ( $res eq 'YES'){ + #examine system bootstrap files + $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$rc_dir; + } else { + $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$etc_dir."/rc.d"; + } else { + print "Failed to locate boostrap directory\n"; + print "wanrouter boot scripts will not be installed\n"; + return; + } + } + + if($zaptel_installed==$TRUE){ + print "Verifying Zaptel boot scripts..."; + #find zaptel start scripts + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; + $res=`$command`; + if ($res =~ /.*S(\d+)zaptel/){ + $zaptel_start_level=$1; + print "Enabled (level:$zaptel_start_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_start_level"; + } + } else { + print "Not installed\n"; + $zaptel_start_level=0; + } + + #find zaptel stop scripts + print "Verifying Zaptel shutdown scripts..."; + $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find ".$rc_dir."/rc6.d/*zaptel"; + $res=`$command`; + if ($res =~ /.*K(\d+)zaptel/){ + $zaptel_stop_level=$1; + print "Enabled (level:$zaptel_stop_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; + } + } else { + print "Not installed\n"; + $zaptel_stop_level=0; + } + if ($zaptel_start_level != 0){ + $wanrouter_start_level=$zaptel_start_level-1; + } + if ($zaptel_stop_level != 0){ + $wanrouter_stop_level=$zaptel_stop_level-1; + } + } + + my $wanrouter_start_script=''; + if($wanrouter_start_level < 10){ + $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; + } else { + $wanrouter_start_script="S".$wanrouter_start_level.$script_name; + } + my $wanrouter_stop_script=''; + if($wanrouter_stop_level < 10){ + $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; + } else { + $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; + } + + $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; + if(system($command) !=0){ + $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; + if(system($command) !=0){ + print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; + print "$script_name boot scripts not installed\n"; + return; + } + } + print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; + if(system($command) !=0){ + print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; + print "$script_name start scripts not installed\n"; + return; + } + } + + print "Enabling $script_name shutdown scripts ...(level:$wanrouter_stop_level)\n"; + @run_levels= ("0","1","6"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; + if(system($command) !=0){ + print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; + print "$script_name stop scripts not installed\n"; + return; + } + } + + if($num_bri_devices != 0){ + #smg_ctrl must start after network + print "Verifying Network boot scripts..."; + $command="find $rc_dir/rc".$current_run_level.".d/*network >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*network"; + $res=`$command`; + if ($res =~ /.*S(\d+)network/){ + $network_start_level=$1; + print "Enabled (level:$network_start_level)\n"; + } else { + print "\nfailed to parse network boot level, assuming $network_start_level"; + } + } else { + print "Not installed\n"; + $network_start_level=0; + } + if ($network_start_level != 0 && $network_start_level > $zaptel_start_level){ + $smg_ctrl_start_level=$network_start_level+1; + print "Enabling smg_ctrl start scripts...(level:$smg_ctrl_start_level)\n"; + $command="install -D -m 755 /usr/sbin/smg_ctrl $rc_dir/init.d/smg_ctrl"; + if(system($command) !=0){ + print "Failed to install smg_ctrl start scripts to $rc_dir/init.d/smg_ctrl"; + print "smg_ctrl start scripts not installed"; + return; + } + my $smg_ctrl_start_script=''; + if($smg_ctrl_start_level < 10){ + $smg_ctrl_start_script="S0".$smg_ctrl_start_level."smg_ctrl"; + } else { + $smg_ctrl_start_script="S".$smg_ctrl_start_level."smg_ctrl"; + } + print "Enabling smg_ctrl boot scripts ...(level:$smg_ctrl_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/smg_ctrl ".$rc_dir."/rc".$run_level.".d/".$smg_ctrl_start_script; + if(system($command) !=0){ + print "Failed to install smg_ctrl init script to $rc_dir/rc$run_level.d/$smg_ctrl_start_script\n"; + print "smg_ctrl start scripts not installed\n"; + return; + } + } + } + + } + + } + +} + + +sub config_ztcfg_start{ + if ($num_zaptel_config ==0 || $silent==$TRUE){ + return; + } + my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) != 0){ + #Zaptel init scripts not installed, prompt for wanpipe_zaptel_start_script + print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + exec_command("cp -f $current_dir/templates/zaptel_cfg_script $wanpipe_conf_dir/scripts/start"); + } + } +} + +sub config_smg_ctrl_start{ + if($num_bri_devices == 0){ + return; + } + print ("Would you like smg_ctrl to start/stop on wanrouter start?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite + my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; + } else { + $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; + } + + if (system($command) == 0){ + print "smgbri start script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + + $command="cp -f ".$current_dir."/templates/smgbri_stop_script ".$wanpipe_conf_dir."/scripts/stop"; + if (system($command) == 0){ + print "smgbri start script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + } +} + +sub check_zaptel{ + if ($modprobe_list =~ /zaptel.ko/){ + $zaptel_installed=$TRUE; + } +} + +sub apply_changes{ + my $asterisk_command=''; + my $bri_command=''; + my $asterisk_restart=$FALSE; + my $res=''; + + system('clear'); + + if($silent==$TRUE){ + $res="Stop now"; + }elsif($is_tdm_api==$TRUE){ + print "\n Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", + "Do not save cfg: Exit", + ""); + }else{ + print "\nZaptel and Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", + "Save cfg: Restart Asterisk & Wanpipe when convenient", + "Save cfg: Stop Asterisk & Wanpipe now", + "Save cfg: Stop Asterisk & Wanpipe when convenient", + "Do not save cfg: Exit", + ""); + } + + + if ($res =~ m/Exit/){ + print "No changes made to your configuration files\n"; + exit 0; + } + if ($res =~ m/now/){ + $asterisk_command='stop now'; + } else { + $asterisk_command='stop when convenient'; + } + + if ($res =~ m/Restart/){ + $asterisk_restart=$TRUE; + } else { + $asterisk_restart=$FALSE; + } + + if ($is_trixbox==$TRUE){ + exec_command("amportal stop"); + unload_zap_modules(); + } elsif ($is_tdm_api==$FALSE ){ + if (`(pidof asterisk)` != 0 ){ + print "\nStopping Asterisk...\n"; + exec_command("asterisk -rx \"$asterisk_command\""); + sleep 2; + while (`(pidof asterisk)` != 0 ){ + if ($asterisk_command eq "stop now"){ + print "Failed to stop asterisk using command: \'$asterisk_command\' \n"; + my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes"); + my $res=&prompt_user_list(@options,""); + + if ( $res =~ m/Force Stop/){ + execute_command("kill -KILL \$(pidof asterisk)"); + } elsif ( $res =~ m/Exit/ ){ + exit(1); + } else { + print "Waiting for asterisk to stop...\n"; + sleep 5; + exec_command("asterisk -rx \"$asterisk_command\""); + } + } else { + #stop when convenient option was selected + print "Waiting for asterisk to stop...\n"; + sleep 3; + } + } + + + + + + }else { + print "\nAsterisk is not running...\n"; + } + + } + + if($num_bri_devices != 0){ + exec_command("/usr/sbin/smg_ctrl stop"); + } + + print "\nStopping Wanpipe...\n"; + exec_command("wanrouter stop all"); + + if ($zaptel_installed==$TRUE){ + if($is_tdm_api==$FALSE){ + print "\nUnloading Zaptel modules...\n"; + unload_zap_modules(); + } + } + + print "\nRemoving old configuration files...\n"; + + exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); + + gen_wanrouter_rc(); + + print "\nCopying new Wanpipe configuration files...\n"; + copy_config_files(); + if($num_bri_devices != 0){ + print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; + exec_command("cp -f $bri_conf_file $bri_conf_file_t"); + exec_command("cp -f $woomera_conf_file $woomera_conf_file_t"); + } + + if ($zaptel_installed==$TRUE){ + if($config_zaptel==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; + exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); + } + } + } + + if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; + exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); + } + } + + if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ + print "\nStarting Wanpipe...\n"; + exec_command("wanrouter start"); + + if($num_bri_devices != 0){ + print "Loading SMG BRI...\n"; + sleep 2; + exec_command("/usr/sbin/smg_ctrl start"); + } + +# if ( ! -e "/$wanpipe_conf_dir/scripts/start" & $is_trixbox==$FALSE && $is_smg==$FALSE ){ + if ($num_zaptel_config != 0){ + print "Loading Zaptel...\n"; + sleep 2; + exec_command("ztcfg -v"); +# print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); +# if (&prompt_user_list("YES","NO","") eq 'YES'){ +# exec_command("cp -f $wanpipe_conf_dir/samples/wanpipe_zaptel_start $wanpipe_conf_dir/scripts/start"); +# } + } + if ($is_trixbox==$TRUE){ + print "\nStarting Amportal...\n"; + exec_command("amportal start"); + sleep 2; + }elsif($config_zapata==$TRUE){ + print "\nStarting Asterisk...\n"; + exec_command("asterisk"); + sleep 2; + + print "\nListing Asterisk channels...\n\n"; + exec_command("asterisk -rx \"zap show channels\""); + print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; + }else{ + } + } + print "\nWanrouter start complete...\n"; +} + + + +sub save_debug_info{ + my $version=`wanrouter version`; + chomp($version); + + my $uname=`uname -a`; + chomp($uname); + + my $issue=''; + + if ($os_type_list =~ m/Linux/){ + $issue=`cat $etc_dir/issue`; + chomp($issue); + } + + my $debug_info="\n"; + $debug_info.="===============================================================\n"; + $debug_info.=" SANGOMA DEBUG INFO FILE \n"; + $debug_info.=" Generated on $date \n"; + $debug_info.="===============================================================\n"; + + $debug_info.="\n\nwanrouter hwprobe\n"; + $debug_info.="@hwprobe\n"; + $debug_info.="\nwanrouter version\n"; + $debug_info.="$version\n"; + $debug_info.="\nKernel \"uname -a\"\n"; + $debug_info.="$uname\n"; + if ($os_type_list =~ m/Linux/){ + $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; + $debug_info.="$issue\n"; + } + $debug_info.="EOF\n"; + + open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; + print FH $debug_info; + close (FH); + exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); +} + +sub get_zapata_context{ + my ($card_model,$card_port)=@_; + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("Select dialplan context for AFT-A%s on port %s\n", $card_model, $card_port); + my $res = &prompt_user_list(@options,$def_zapata_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_zapata_context); + } + + $context=$res_context; + }elsif($res eq $def_zapata_context){ + $context=$def_zapata_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + $context=$silent_zapata_context; + } + $def_zapata_context=$context; + return $context; +} + + +sub get_woomera_context{ + my ($group,$card_model,$card_port,$bri_type)=@_; + + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($bri_type eq 'bri_nt'){ + @options = ("from-internal","Custom"); + } elsif ($bri_type eq 'bri_te'){ + @options = ("from-pstn","Custom"); + } + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("\nSelect dialplan context for group:%d\n", $group); + my $res = &prompt_user_list(@options,$def_woomera_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_woomera_context); + } + + $context=$res_context; + }elsif($res eq $def_woomera_context){ + $context=$def_woomera_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + $context=$silent_woomera_context; + } + $def_woomera_context=$context; + return $context; +} + + + +sub gen_wanrouter_rc{ + #update wanpipe startup sequence + my $rcfile=""; + if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { + open (FH,"$wanrouter_rc_template"); + } + while () { + $rcfile .= $_; + } + close (FH); + open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); + $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; + print FH $rcfile; + close (FH); +} + +sub prepare_files{ + + if ($is_trixbox==$TRUE){ + $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; + $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; + $zapata_conf_file_t="$asterisk_conf_dir/zapata-auto.conf"; + } + + if ($silent==$FALSE){ + if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ + print "Would you like to generate $zapata_conf_file_t\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $config_zapata = $FALSE; + } + } + } + +#remove temp files + my $tmp_cfg_dir="$current_dir"."/"."$cfg_dir"; + if ( -d "$current_dir"."/"."$cfg_dir") { + exec_command("rm -f $current_dir/$cfg_dir/*"); + } +#backup existing configuration files + if ( -f $zaptel_conf_file_t ) { + exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); + } + + if ( -f $zapata_conf_file_t ) { + exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); + } +} + +sub clean_files{ + exec_command("rm -rf $current_dir/$cfg_dir"); +} + + +sub write_zapata_conf{ + my $zp_file=""; + open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + + $zp_file.=$zapata_conf; + + open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; + print FH $zp_file; + close(FH); +} + +sub copy_config_files{ + my @wanpipe_files = split / /, $cfg_string; + exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc $wanpipe_conf_dir"); + foreach my $wanpipe_file (@wanpipe_files) { + exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf $wanpipe_conf_dir"); + } +} + +sub unload_zap_modules{ + my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); + foreach my $module (@modules_list) { + if ($modprobe_list =~ m/$module/){ + exec_command("$module_unload $module"); + } + } +} + +sub write_zaptel_conf{ + my $zp_file=""; + open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + $zp_file=$zp_file.$zaptel_conf; + open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; + print FH $zp_file; + close(FH); +} + +sub summary{ + if($devnum==1){ + system('clear'); + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); + exit 0; + }else{ + if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ + write_zaptel_conf(); + } + if ($num_bri_devices != 0 ){ + write_bri_conf(); + write_woomera_conf(); + } + if ($config_zapata==$TRUE){ + write_zapata_conf(); + } + save_debug_info(); + system('clear'); + my $file_list = 1; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); + print(" $num_bri_devices_total ISDN BRI port(s) detected, $num_bri_devices configured\n"); + print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); + + print "\nConfigurator has created the following files:\n"; + print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; + $file_list++; + + if ($num_bri_devices != 0){ + print "\t$file_list. sangoma_brid config file $wanpipe_conf_dir/smg_bri\n"; + $file_list++; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; + } + + if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ + print "\n\nYour original configuration files will be saved to:\n"; + $file_list=1; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. $zaptel_conf_file_t.bak \n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. $zapata_conf_file_t.bak \n\n"; + } + + print "\nYour configuration has been saved in $debug_tarball.\n"; + print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } +} + + +sub exec_command{ + my @command = @_; + if (system(@command) != 0 ){ + print "Error executing command:\n@command\n\n"; + print "Would you like to continue?\n"; + if(&prompt_user_list("No - exit", "YES", "No") eq 'YES'){ + return $?; + } else { + exit $?; + } + } + return $?; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "def=\"$defaultValue\": "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $defaultValue = @list[$#list]; + + my $i; + my $valid = 0; + for $i (0..$#list-1) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + my $list_sz = $#list; + print "[1-$list_sz"; + if ( ! $defaultValue eq ''){ + print ", ENTER=\'$defaultValue\']:"; + }else{ + print "]:"; + } + $| = 1; + $_ = ; + chomp; + if ( $_ eq '' & ! $defaultValue eq ''){ + print "\n"; + return $defaultValue; + } + + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $list_sz) { + print "\nError: Invalid option, input a value between 1 and $list_sz \n"; + } else { + print "\n"; + return @list[$1-1] ; + } + } else { + print "\nError: Invalid option, input an integer\n"; + } + } +} + +sub read_args { + my $arg_num; + foreach $arg_num (0 .. $#ARGV) { + $_ = $ARGV[$arg_num]; + if( /^--trixbox$/){ + $is_trixbox=$TRUE; + }elsif ( /^--tdm_api/){ + $is_tdm_api=$TRUE; + }elsif ( /^--smg$/){ + $is_smg=$TRUE; + }elsif ( /^--no_boot$/){ + $no_boot=$TRUE + }elsif ( /^--silent$/){ + $silent=$TRUE; + }elsif ( /^--no-zapata$/){ + $config_zapata=$FALSE; + }elsif ( /^--no-zaptel$/){ + $config_zaptel=$FALSE; + }elsif ( $_ =~ /--fe_media=(\w+)/){ + $silent_femedia=$1; + if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ + printf("Invalid value for fe_media, should be T1/E1\n"); + exit(1); + } + }elsif ( $_ =~ /--fe_lcode=(\w+)/){ + $silent_felcode=$1; + if(!($silent_felcode eq 'B8ZS' || $silent_felcode eq 'HDB3' || $silent_felcode eq 'AMI')){ + printf("Invalid value for fe_lcode, should be B8ZS/HDB3/AMI \n"); + exit(1); + } + }elsif ( $_ =~ /--fe_frame=(\w+)/){ + $silent_feframe=$1; + if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ + printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); + exit(1); + } + }elsif ( $_ =~ /--tdm_law=(\w+)/){ + $silent_tdm_law=$1; + if(!($silent_tdm_law eq 'MULAW' || $silent_tdm_law eq 'ALAW')){ + printf("Invalid value for tdm_law, should be MULAW/ALAW\n"); + exit(1); + } + }elsif ( $_ =~ /--fe_clock=(\w+)/){ + $silent_feclock=$1; + if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ + printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); + exit(1); + } + }elsif ( $_ =~ /--signalling=(\w+)/){ + my $tmp_signalling=$1; + if ($tmp_signalling eq 'em'){ + $silent_signalling="E & M"; + }elsif ($tmp_signalling eq 'em_w'){ + $silent_signalling="E & M Wink"; + }elsif ($tmp_signalling eq 'pri_cpe'){ + $silent_signalling="PRI CPE"; + }elsif ($tmp_signalling eq 'pri_net'){ + $silent_signalling="PRI NET"; + }elsif ($tmp_signalling eq 'fxs_ls'){ + $silent_signalling="FXS - Loop Start"; + }elsif ($tmp_signalling eq 'fxs_gs'){ + $silent_signalling="FXS - Ground Start"; + }elsif ($tmp_signalling eq 'fxs_ks'){ + $silent_signalling="FXS - Kewl Start"; + }elsif ($tmp_signalling eq 'fxo_ls'){ + $silent_signalling="FXO - Loop Start"; + }elsif ($tmp_signalling eq 'fxo_gs'){ + $silent_signalling="FXO - Ground Start"; + }elsif ($tmp_signalling eq 'fxo_ks'){ + $silent_signalling="FXO - Kewl Start"; + }else{ + printf("Invalid option for --signalling, options are\n"); + printf("\t pri_cpe/pri_net/em/em_w\n"); + printf("\t em/em_w\n"); + printf("\t fxo_ls/fxo_gs/fxo_ks\n"); + printf("\t fxs_ls/fxs_gs/fxs_ks\n"); + exit(1); + } + }elsif ( $_ =~ /--pri_switchtype=(\w+)/){ + my $tmp_switchtype=$1; + if ($tmp_switchtype eq 'national'){ + $silent_pri_switchtype="national" + }elsif ($tmp_switchtype eq 'dms100'){ + $silent_pri_switchtype="dms100" + }elsif ($tmp_switchtype eq '4ess'){ + $silent_pri_switchtype="4ess" + }elsif ($tmp_switchtype eq '5ess'){ + $silent_pri_switchtype="5ess" + }elsif ($tmp_switchtype eq 'euroisdn'){ + $silent_pri_switchtype="euroisdn" + }elsif ($tmp_switchtype eq 'ni1'){ + $silent_pri_switchtype="ni1" + }elsif ($tmp_switchtype eq 'qsig'){ + $silent_pri_switchtype="qsig" + } else { + printf("Invalid option for --pri_switchtype, options are\n"); + printf("\t national/dms100/4ess/5ess/euroisdn/ni1/qsig"); + exit(1); + } + }elsif ( $_ =~ /--conf_dir=(.*)/){ + $etc_dir=$1; + if (! -d $etc_dir){ + printf("Error: directory $1 does not exist\n"); + exit(1); + } + } + } + + if ($is_trixbox==$TRUE){ + print "\nGenerating configuration files for Trixbox\n"; + } + if ($is_smg==$TRUE){ + print "\nGenerating configuration files for SS7\n"; + } + if ($is_tdm_api==$TRUE){ + $config_zapata = $FALSE; + } + +} + +#------------------------------BRI FUNCTIONS------------------------------------# +sub get_bri_country { + $def_bri_country = "europe"; + return $def_bri_country; +} + +sub get_bri_group{ + my $group; + my $res_group=&prompt_user("\nInput the group for this port\n",$def_bri_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ + print "Invalid group, input an integer greater than 0\n"; + $res_group=&prompt_user("Input the group for this port",$def_bri_group); + } + $group=$res_group; + $def_bri_group=$group; + return $def_bri_group; +} + + +sub get_bri_operator { +#warning returning ETSI + $def_bri_operator = "etsi"; + return $def_bri_operator; + + + + my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", + "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", + "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); + + my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); + + my $res = &prompt_user_list(@options,$def_switchtype); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_operator=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + +sub write_bri_conf{ + my $bri_file=""; + open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; + while () { + $bri_file .= $_; + } + close (FH); + $bri_file=$bri_file.$bri_conf; + open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; + print FH $bri_file; + close(FH); +} + +sub write_woomera_conf{ + my $woomera_file=""; + open(FH, "$woomera_conf_template") or die "cannot open $woomera_conf_template"; + while () { + $woomera_file .= $_; + } + close (FH); + $woomera_file=$woomera_file.$woomera_conf; + open(FH, ">$woomera_conf_file") or die "cannot open $woomera_conf_file"; + print FH $woomera_file; + close(FH); +} + + +sub get_bri_conn_type{ + my $conn_type; + + my @options = ( "Point to multipoint", "Point to point"); + my @options_val = ("point_to_multipoint", "point_to_point"); + + my $res = &prompt_user_list(@options,$def_bri_conn_type); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_conn_type=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid BRI connection type\n"; + exit 1; +} + + + + +sub config_bri{ + if($is_smg!=$TRUE && $is_trixbox==$FALSE){ + return; + } + if ($silent==$TRUE){ + return; + } + my $a50x; + if (!$first_cfg) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring ISDN BRI cards [A500]\n"; + print "------------------------------------\n"; + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ + $skip_card=$FALSE; + if ($1 eq '500'){ + my $card = eval {new Card(); } or die ($@); + + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + + my $hwec=0; + if($6 gt 0){ + $hwec=1; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + + if ($card->card_model eq '500'){ + $num_bri_devices_total++; + if($5 eq '1'){ + $bri_device_has_master_clock=$FALSE; + } + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + +select_bri_option: + print "\nWould you like to configure AFT-A$1 port $5 on slot:$3 bus:$4\n"; + my @options=("YES", "NO", "Exit"); + $def_bri_option=&prompt_user_list(@options,$def_bri_option); + if($def_bri_option eq 'YES'){ + $skip_card=$FALSE; + $bri_conf.="\n;Sangoma AFT-A$1 port $5 [slot:$3 bus:$4 span:$current_tdmapi_span]"; + }elsif($def_bri_option eq 'NO'){ + $skip_card=$TRUE; + }else{ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } else { + goto select_bri_option; + } + } + if ($skip_card==$FALSE){ + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + $a50x = eval {new A50x(); } or die ($@); + $a50x->card($card); + $a50x->fe_line($5); + $devnum++; + $num_bri_devices++; + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; +# $a50x->gen_wanpipe_conf(); + }else{ + print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; + prompt_user("Press any key to continue"); + } + + } + } + }elsif (($dev =~ /(\d+):NT/ | + $dev =~ /(\d+):TE/ )& + $skip_card==$FALSE ){ + + + my $context=""; + my $group=""; + my $bri_pos=$a50x->card->tdmv_span_no; + + printf("\nConfiguring port %d on AFT-A%d [slot:%d bus:%d span:%d]\n", $a50x->fe_line(), $a50x->card->card_model(), $a50x->card->pci_slot(), $a50x->card->pci_bus(), $current_tdmapi_span-1); + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $conn_type=get_bri_conn_type(); + my $country=get_bri_country(); + my $operator=get_bri_operator(); + if($is_trixbox==$TRUE){ + if ( $dev =~ /(\d+):NT/ ){ + $context="from-internal"; + $group=1; + } else { + $context="from-zaptel"; + $group=0; + } + } else { + $group=get_bri_group(); + #if a context has already been assigned to this group, do not prompt for options + foreach my $f_group (@woomera_groups) { + if($f_group eq $group){ + $context="WOOMERA_NO_CONFIG"; + } + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + if ( $dev =~ /(\d+):NT/ ){ + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_nt'); + } else { + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_te'); + } + push(@woomera_groups, $group); + + } + } + $a50x->gen_wanpipe_conf(); + if ( $dev =~ /(\d+):NT/ ){ + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_nt", $group, $country, $operator, $conn_type); + } else { + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + $woomera_conf.=$a50x->gen_woomera_conf($group, $context); + } + + } + } +# prompt_user("Press any key to continue"); + if($num_bri_devices_total!=0){ + print("\nISBN BRI card configuration complete\n\n"); + prompt_user("Press any key to continue"); + } else { + print("\nNo Sangoma ISDN BRI cards detected\n\n"); + prompt_user("Press any key to continue"); + + } +} + + + + + +#------------------------------T1/E1 FUNCTIONS------------------------------------# + +sub get_te_ref_clock{ + my @list_normal_clocks=@_; + my @f_list_normal_clocks; + my $f_port; + foreach my $port (@list_normal_clocks) { + if ($port eq '0'){ + $f_port = "Free run"; + } else { + $f_port = "Port ".$port; + } + push(@f_list_normal_clocks, $f_port); + } + + my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); + my $i; + + for $i (0..$#f_list_normal_clocks){ + if ( $res eq @f_list_normal_clocks[$i] ){ + return @list_normal_clocks[$i]; + } + } + + print "Internal error: Invalid reference clock\n"; + exit 1; + +} + + +sub prompt_user_hw_dchan{ + my ($card_model, $port, $port_femedia) = @_; + my $res_dchan=''; + my $dchan; + + printf("Hardware HDLC can be performed on the data channel.\n"); +prompt_hw_dchan: + my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); + while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ + print "Invalid channel, input an integer (0 for unused).\n"; + $res_dchan=&prompt_user("Select the data channel","0"); + } + if ( $res_dchan < 0){ + printf("Error: channel cannot have negative value\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ( $port_femedia eq 'T1' && $res_dchan > 24){ + printf("Error: only 24 channels available on T1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + }elsif ($port_femedia eq 'E1' && $res_dchan > 31){ + printf("Error: only 31 channels available on E1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ($res_dchan == 0){ + printf("HW HDLC channel not used\n"); + }else{ + printf("HW HDLC channel set to:%d\n", $res_dchan); + } + return $res_dchan; +} + + + +sub get_zapata_group{ + my ($card_model,$card_port,$context)=@_; + my $group=''; + if($is_trixbox==$TRUE){ + if($context eq "from-zaptel"){ + $group=0; + return $group; + }elsif($context eq "from-internal"){ + $group=1; + return $group; + }else{ + print "Internal error:invalid group for Trixbox\n"; + } + }else{ + if($context eq "from-pstn"){ + $group=0; + }elsif($context eq "from-internal"){ + $group=1; + }else{ + my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)){ + print "Invalid group, input an integer.\n"; + $res_group=&prompt_user("Input the group for this port",$def_zapata_group); + } + $group=$res_group; + $def_zapata_group=$group; + } + } + + return $group; +} + + + +sub prompt_hw_dtmf { +#HW DTMF not supported in the 3.2 drivers +# return "NO"; + print("Would you like to enable hardware DTMF detection?\n"); + my @options = ("YES","NO"); + $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); + return $def_hw_dtmf; +} + +sub prompt_tdm_law { + print("Which codec will be used?\n"); + my @options = ("MULAW - North America","ALAW - Europe"); + my @options_val = ("MULAW", "ALAW"); + my $res = &prompt_user_list(@options, $def_tdm_law); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_tdm_law=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid TDM LAW type\n"; + exit 1; +} + + +sub get_pri_switchtype { + my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); + my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); + my $res = &prompt_user_list(@options,$def_switchtype); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_switchtype=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + + +sub gen_ss7_voicechans{ + my @ss7_array = @_; + my $T1CHANS = pop(@ss7_array); + my $count = @ss7_array; + my $output =''; + my $chan_in = 1; + my $chan_de = 0; + my $flag = 0; + my $i = 0; + my $j = 0; + + while($i < $count){ + $j = $i + 1; + if ($ss7_array[$i] > 2 && $i == 0){ + $chan_de = $ss7_array[$i] - 1; + $output .= "1-$chan_de"; + $flag = 1; + }elsif ($ss7_array[$i] == 2 && $i == 0){ + $output .= "1"; + $flag = 1; + } + + if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ + goto Incrementing; + }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ + goto Incrementing; + } + + if ($i < ($count-1)){ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < ($ss7_array[$j]-1)){ + $chan_de = $ss7_array[$j] - 1; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$chan_in"; + }else{ + $output .= "$chan_in"; + $flag = 1; + } + } + }else{ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < $T1CHANS){ + $chan_de = $T1CHANS; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$T1CHANS"; + }else{ + $output .= "$T1CHANS"; + $flag = 1; + } + } + } + +Incrementing: + $i++; + } + return $output; +} + +sub prompt_user_ss7_chans{ + my @ss7_string = @_; + my $def_ss7_group_chan = ''; + + my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + +CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ + print("ERROR: Invalid channel number, input an integer only.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); +} + if ($line_media eq 'T1'){ + while ($ss7_group_chan>24 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 24 channels in T1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +}elsif ($line_media eq 'E1'){ + while ($ss7_group_chan>31 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 31 channels in E1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +} + return $ss7_group_chan; +} + + + + + + +sub config_t1e1{ + if (!$first_cfg) { + system('clear'); + } + print "---------------------------------------------\n"; + print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; + print "---------------------------------------------\n"; + + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + + if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ + #do not count analog devices + $num_digital_devices_total++; + } + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + + my $hwec=0; + if ( $dev =~ /HWEC=(\d+)/){ + if($1 gt 0){ + $hwec=1; + } + } + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + my $port=$6; + if ($6 eq 'PRI') { + $port=$5; + } + + if ( $card->card_model eq '101' | + $card->card_model eq '102' | + $card->card_model eq '104' | + $card->card_model eq '108' ){ + if (!$first_cfg) { + system('clear'); + } + if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ + print "A$1 detected on slot:$3 bus:$4\n"; + $device_has_normal_clock=$FALSE; + @device_normal_clocks = ("0"); + } + # if (!$first_cfg) { + # system('clear'); + # } + $first_cfg=0; + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; + print "$msg"; + print "-----------------------------------------------------------\n"; + my $fe_media = ''; + if ($silent==$TRUE){ + $fe_media = $silent_femedia; + } else { + printf ("\nSelect media type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + my @options = ("T1", "E1", "Unused","Exit"); + $fe_media = prompt_user_list( @options, $def_femedia); + } + + if ( $fe_media eq 'Exit'){ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } + }elsif ( $fe_media eq 'Unused'){ + $def_femedia=$fe_media; + my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; + print "$msg"; + prompt_user("Press any key to continue"); + }else{ + if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ + $device_has_hwec=$TRUE; + } + + $def_femedia=$fe_media; + $cfg_string.="wanpipe$devnum "; + my $a10x; + + if ($1 !~ m/104/ && $2 !~ m/SH/) { + $a10x = eval {new A10u(); } or die ($@); + $a10x->card($card); + if ($5 eq "A") { + $a10x->fe_line("1"); + } else { + $a10x->fe_line("2"); + } + } else { + $a10x = eval {new A10x(); } or die ($@); + if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + $a10x->card($card); + $a10x->fe_line($6); + } + + $card->first_chan($current_zap_channel); + $a10x->fe_media($fe_media); + if ( $fe_media eq 'T1' ){ + $max_chans = 24; + $line_media = 'T1'; + + #$def_te_sig_mode=''; + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + + + if ($silent==$FALSE){ + printf ("Configuring port %s on AFT-A%s as: %s, coding:%s, framing:%s.\n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe, + $port); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("B8ZS", "AMI"); + $def_felcode= &prompt_user_lit(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("ESF", "D4"); + $def_feframe= &prompt_user_list(@options, $def_feframe); + } + + + } else { + $def_felcode=$silent_felcode; + $def_feframe=$silent_feframe; + } + + + }else{ #fe_media = E1 + $max_chans = 31; + $line_media = 'E1'; + + + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("HDB3", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("CRC4", "NCRC4","UNFRAMED"); + $def_feframe = &prompt_user_list(@options, $def_feframe); + +# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); +# my @options = ("CCS - Clear channel signalling ", "CAS"); +# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); + + } + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode on AFT-A%s port %s\n",$card->card_model, $port); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + } else { + $def_te_sig_mode="CAS"; + } + + + } else { + $def_felcode=$silent_felcode; + $def_feframe=$silent_feframe; + } + + + } + $a10x->fe_lcode($def_felcode); + $a10x->fe_frame($def_feframe); + if($silent==$FALSE){ + my @options = ("NORMAL", "MASTER"); + printf ("Select clock for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_feclock=&prompt_user_list(@options, $def_feclock); + } else { + $def_feclock=$silent_feclock; + } + + $a10x->fe_clock($def_feclock); + if ( $def_feclock eq 'NORMAL') { + $device_has_normal_clock=$TRUE; + push(@device_normal_clocks, $a10x->fe_line); + } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ + printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", + $card->card_model, + $port, + $card->pci_slot, + $card->pci_bus); + printf(" Free run: Use internal oscillator on card [default] \n"); + printf(" Port N: Sync with clock from port N \n\n"); + + printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); + $a10x->te_ref_clock($def_te_ref_clock); + } + + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + } + + + + my @options=""; + if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_smg==$TRUE && $zaptel_installed==$FALSE){ + @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_tdm_api==$TRUE){ + $def_signalling="TDM API"; + } else { + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); + } + if ($silent==$FALSE){ + if( $is_tdm_api == $FALSE){ + printf ("Select signalling type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_signalling=&prompt_user_list(@options,$def_signalling); + } + } else { + $def_signalling=$silent_signalling; + } + $a10x->signalling($def_signalling); + + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + + } else { + $def_te_sig_mode="CAS"; + } + $a10x->te_sig_mode($def_te_sig_mode); + + my $ss7_chan; + my $ss7_group_start; + my $ss7_group_end; + my @ss7_chan_array; + my @ss7_sorted; + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_option(1); + print("Choose an option below to configure SS7 signalling channels:\n"); + my @options =("Configure individual signalling channels(e.g #1,#10)", + "Configure consecutive signalling channels(e.g #1-#16)"); + my $res = &prompt_user_list(@options, ""); + if ( $res eq 'Configure individual signalling channels(e.g #1,#10)'){ + goto SS7CHAN; + while (1){ + print("\nAny other SS7 signalling channel to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7CHAN: + $ss7_chan = prompt_user_ss7_chans('Specify the channel for SS7 signalling(24 for T1? 16 for E1?)'); + push(@ss7_chan_array, $ss7_chan); + $ss7_array_length = @ss7_chan_array; + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + }else{ + goto SS7GROUP; + while(1){ + print("\nAny other SS7 consecutive signalling channels to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7GROUP: + $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); + $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); + if ($ss7_group_start > $ss7_group_end){ + print("The starting channel number is bigger than the ending one!\n"); + goto SS7GROUP; + } + my $i = 0; + for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ + push(@ss7_chan_array, $i); + my @remove_duplicate; + @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); + $ss7_array_length = @ss7_chan_array; + + if ($ss7_array_length > $max_chans){ + print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); + + @ss7_chan_array = (); + goto SS7GROUP; + } + } + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + } + +ENDSS7CONFIG: + + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); + my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); + $ss7_tdmvoicechans = $ss7_voicechans; + + if ($ss7_voicechans =~ m/(\d+)/){ + $a10x->ss7_tdminterface($1); + } + + $a10x->ss7_tdmchan($ss7_voicechans); + + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + + #wanrouter start/stop for signalling span is controlled by ss7boxd + #$startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ + $a10x->ss7_option(2); + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + + }elsif ($a10x->signalling eq 'TDM API'){ + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); + } + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + }else{ + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $startup_string.="wanpipe$devnum "; + $current_zap_span++; + $current_zap_channel+=$max_chans; + } + + + + if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ + if ($silent==$FALSE && $config_zapata==$TRUE){ + printf ("Select switchtype for AFT-A%s on port %s \n", $card->card_model, $port); + $a10x->pri_switchtype(get_pri_switchtype()); + } else { + $a10x->pri_switchtype($silent_pri_switchtype); + } + } + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_subinterface(1); + $a10x->gen_wanpipe_ss7_subinterfaces(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(2); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + my $ss7_element; + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + + $a10x->gen_wanpipe_conf(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + }else{ + $a10x->gen_wanpipe_conf(); + } + + if ($is_smg==$TRUE && $config_zapata==$FALSE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' + | $a10x->signalling eq 'No Signaling (Voice Only)')){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ + + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + } + }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + }elsif ($is_tdm_api == $FALSE){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + $devnum++; + $num_digital_devices++; + my $msg ="\n\nPort ".$port." on A".$card->card_model." configuration complete...\n"; + print "$msg"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + } + + + } + + } + } + if($num_digital_devices_total!=0){ + print("\nT1/E1 card configuration complete.\n"); + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + $first_cfg=0; + } +# close SCR; +} + + +#------------------------------ANALOG FUNCTIONS------------------------------------# + + +sub config_analog{ + if($is_tdm_api==$TRUE){ + return; + } + my $a20x; + if (!$first_cfg) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring analog cards [A200/A400]\n"; + print "------------------------------------\n"; + + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ + $skip_card=$FALSE; + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + my $hwec=$7; + if ($hwec==0){ + $card->hwec_mode('NO'); + } + else{ + $card->hwec_mode('YES'); + } + if ($card->card_model eq '200' | $card->card_model eq '400'){ + $num_analog_devices_total++; + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + if($is_trixbox==$FALSE){ + if ($silent==$FALSE){ + print "\nWould you like to configure AFT-A$1 on slot:$3 bus:$4\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $skip_card=$TRUE; + } + } + } + if ($skip_card==$FALSE){ + + $a20x = eval {new A20x(); } or die ($@); + $a20x->card($card); + $card->first_chan($current_zap_channel); + + if ( $device_has_hwec==$TRUE){ + print "Will this AFT-A$1 synchronize with an existing Sangoma T1/E1 card?\n"; + print "\n WARNING: for hardware and firmware requirements, check:\n"; + print " http://wiki.sangoma.com/t1e1analogfaxing\n"; + + if (&prompt_user_list(("NO","YES","")) eq 'NO'){ + $a20x->rm_network_sync('NO'); + } else { + $a20x->rm_network_sync('YES'); + } + } + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + $a20x->tdm_law(&prompt_tdm_law()); + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + $a20x->tdm_law($silent_tdm_law); + } + + + print "A$1 configured on slot:$3 bus:$4 span:$current_zap_span\n"; + $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + $current_zap_channel+=24; + my $i; + $devnum++; + $num_analog_devices++; + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + $a20x->gen_wanpipe_conf(); + + }else{ + print "A$1 on slot:$3 bus:$4 not configured\n"; + prompt_user("Press any key to continue"); + } + } + }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-internal"); + $a20x->card->zap_group("1"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); + }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-zaptel"); + $a20x->card->zap_group("0"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); + } + } + if($num_analog_devices_total!=0){ + print("\nAnalog card configuration complete\n\n"); + if( $silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } + +} + diff --git a/util/wancfg_zaptel/: b/util/wancfg_zaptel/: new file mode 100644 index 0000000..2378160 --- /dev/null +++ b/util/wancfg_zaptel/: @@ -0,0 +1,2484 @@ +#!/usr/bin/perl +# config-zaptel.pl +# Sangoma Zaptel/TDM API/SMG Configuration Script. +# +# Copyright (c) 2006, Sangoma Technologies Inc. +# +# 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. +# ---------------------------------------------------------------------------- +# Jan 02 2008 2.11 David Yat Sin Support for per span configuration in silent mode +# Jan 02 2008 2.10 David Yat Sin Added option for BRI master clock +# Dec 15 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 +# Nov 29 2007 2.8 David Yat Sin Support for BRI cards on Trixbox +# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option +# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode +# Jul 20, 2007 2.5 David Yat Sin silent option +# Jun 13, 2007 Yuan Shen SS7 support +# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major +# changes to script. +# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl +# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong +# context +# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards +# Oct 13, 2006 David Yat Sin Added --opermode and --law option +# Oct 12, 2006 David Yat Sin Initial version +# ============================================================================ + +system('clear'); +print "\n#############################################i##########################"; +print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI/BOOT Configuration Script #"; +print "\n# v2.10 #"; +print "\n# Sangoma Technologies Inc. #"; +print "\n# Copyright(c) 2007. #"; +print "\n########################################################################\n\n"; + +use strict; +#use warnings; +#use diagnostics; +use Card; +use A10x; +use A10u; +use A20x; +use A50x; + + +my $FALSE = 1; +my $TRUE = 0; +my $zaptelprobe=' '; + +my $etc_dir=""; +my $include_dir=""; +my $module_list=""; +my $module_load=""; +my $module_unload=""; +my $os_type_name=""; +my $dchan_str="dchan"; + +my $os_type_list=`sysctl -a |grep ostype`; +if ($os_type_list =~ m/Linux/){ + $os_type_name="Linux"; + $etc_dir="/etc"; + $module_load="modprobe"; + $module_unload="modprobe -r"; + $module_list="modprobe -l"; + $include_dir="/usr/include"; +}elsif ($os_type_list =~ m/FreeBSD/){ + $os_type_name="FreeBSD"; + $etc_dir="/usr/local/etc"; + $module_load="kldload"; + $module_unload="kldunload"; + $module_list="kldstat"; +}else{ + print("Failed to determine OS type\n"); + print("Exiting...\n"); + exit(1); +} + + +my $no_boot=$FALSE; +my $boot_only=$FALSE; +#HW DTMF NOT SUPPORTED in 3.2 drivers +#my $no_hwdtmf=$FALSE; +my $no_hwdtmf=$TRUE; +my $startup_string=""; +my $cfg_string=""; +my $first_cfg=1; +my $zaptel_conf=""; +my $zapata_conf=""; +my $bri_conf=""; +my $woomera_conf=""; +my $devnum=1; +my $current_zap_span=1; +my $current_tdmapi_span=1; +#my $current_bri_span=1; +my $current_zap_channel=1; +my $num_analog_devices=0; +my $num_analog_devices_total=0; +my $num_bri_devices=0; +my $num_bri_devices_total=0; +my $num_digital_devices=0; +my $num_digital_devices_total=0; +my $num_ss7_config=0; +my $num_zaptel_config=0; +my $line_media=''; +my $max_chans=0; +my $ss7_tdmvoicechans=''; +my $ss7_array_length=0; + + + +my $device_has_hwec=$FALSE; +my $device_has_normal_clock=$FALSE; +my @device_normal_clocks=("0"); +my @woomera_groups=("0"); +my $bri_device_has_master_clock=$FALSE; + +my $is_tdm_api=$FALSE; + +my $def_femedia=''; +my $def_feframe=''; +my $def_feclock=''; +my $def_bri_option=''; +my $def_signalling=''; +my $def_switchtype=''; +my $def_zapata_context=''; +my $def_woomera_context=''; +my $def_zapata_group=''; +my $def_te_ref_clock=''; +my $def_tdmv_dchan=0; +my $def_woomera_group=''; +my $def_felcode=''; +my $def_feframe=''; +my $def_te_sig_mode=''; + +my $def_hw_dtmf="YES"; +my $def_tdm_law=''; + + +my @silent_femedias; +my @silent_feframes; +my @silent_felcodes; +my @silent_tdm_laws; +my @silent_feclocks; +my @silent_signallings; +my @silent_pri_switchtypes; +my @silent_zapata_contexts; +my @silent_woomera_contexts; +my @silent_zapata_groups; +my @silent_bri_conn_types; +my @silent_woomera_groups; +my @silent_hwdtmfs; +my @silent_first_chans; +my @silent_last_chans; + + +my $silent_hwdtmf; +my $silent_femedia="T1"; +my $silent_feframe="ESF"; +#my $silent_feframe_e1="CRC4"; + +my $silent_felcode="B8ZS"; +my $silent_tdm_law="MULAW"; + + +my $silent_feclock="NORMAL"; +my $silent_signalling="PRI CPE"; +my $silent_pri_switchtype="national"; +my $silent_zapata_context="from-pstn"; +my $silent_woomera_context="from-pstn"; +my $silent_zapata_group="0"; +my $silent_te_sig_mode='CCS'; + +my $silent_bri_conn_type="point_to_multipoint"; +my $silent_woomera_group="1"; + +my $silent_first_chan=1; +my $silent_last_chan=24; + +my $def_bri_country="europe"; +my $def_bri_operator="etsi"; +my $def_bri_conn_type="Point to multipoint"; + +my $is_trixbox = $FALSE; +my $silent = $FALSE; +my $config_zaptel = $TRUE; +my $config_zapata = $TRUE; +my $is_smg = $FALSE; + +my $tdm_api_span_num=0; +my $zaptel_installed=$FALSE; +my $modprobe_list=`$module_list`; + + +read_args(); +check_zaptel(); +if($boot_only==$TRUE){ + exit( &config_boot()); +} +my $current_dir=`pwd`; +chomp($current_dir); +my $cfg_dir='tmp_cfg'; +my $curdircfg="$current_dir"."/"."$cfg_dir"; + +unless ( -d $curdircfg ) { + $curdircfg = "mkdir " . $curdircfg; + system ($curdircfg); +} + + +my $debug_info_file="$current_dir/$cfg_dir/debug_info"; +my @hwprobe=`wanrouter hwprobe verbose`; + +my $wanpipe_conf_dir="$etc_dir/wanpipe"; +my $asterisk_conf_dir="$etc_dir/asterisk"; + +my $wanrouter_rc_template="$current_dir/templates/wanrouter.rc.template"; + +my $zaptel_conf_template="$current_dir/templates/zaptel.conf"; +my $zaptel_conf_file="$current_dir/$cfg_dir/zaptel.conf"; +my $zaptel_conf_file_t="$etc_dir/zaptel.conf"; + +my $zapata_conf_template="$current_dir/templates/zapata.conf"; +my $zapata_conf_file="$current_dir/$cfg_dir/zapata.conf"; +my $zapata_conf_file_t="$asterisk_conf_dir/zapata.conf"; + +my $bri_conf_template="$current_dir/templates/smg_bri.conf"; +my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; +my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; + +my $woomera_conf_template="$current_dir/templates/woomera.conf"; +my $woomera_conf_file="$current_dir/$cfg_dir/woomera.conf"; +my $woomera_conf_file_t="$asterisk_conf_dir/woomera.conf"; + +my $date=`date +%F`; +chomp($date); +my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; + +set_zaptel_hwhdlc(); +prepare_files(); +config_t1e1(); +config_bri(); +config_analog(); +summary(); +apply_changes(); +config_boot(); +config_ztcfg_start(); +config_smg_ctrl_start(); +clean_files(); +print "Sangoma cards configuration complete, exiting...\n\n"; + + +#######################################FUNCTIONS################################################## + + +sub set_zaptel_hwhdlc{ + if ((system("grep hdlc_hard_xmit '$include_dir/zaptel/zaptel.h'>/dev/null 2>/dev/null")==0)){ + $dchan_str="hardhdlc"; + } +} + +sub config_boot{ + if($no_boot==$TRUE){ + return; + } + my $script_name="wanrouter"; + my $current_run_level=3; + my $zaptel_start_level=9; + my $zaptel_stop_level=92; + my $network_start_level=10; + my $wanrouter_start_level=8; + my $wanrouter_stop_level=91; + my $smg_ctrl_start_level=11; + my $command=''; + my $rc_dir=$etc_dir; + + if ($os_type_list =~ m/FreeBSD/){ + return; + } + my $res=`cat $etc_dir/inittab |grep id`; + if ($res =~ /id:(\d+):initdefault/){ + $current_run_level=$1; + print "Current boot level is $current_run_level\n"; + } else { + print "Warning: Failed to determine init boot level, assuming 3\n"; + $current_run_level=3; + } + + + print "\nWanrouter boot scripts configuration...\n\n"; + print "Removing existing $script_name boot scripts..."; + $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; + if(system($command) == 0){ + print "OK\n"; + } else { + print "Not installed\n"; + } + if($num_ss7_config!=0){ + $script_name="smgss7_init_ctrl"; + } + + my $res='YES'; + if($silent==$FALSE){ + print ("Would you like $script_name to start on system boot?\n"); + $res= &prompt_user_list("YES","NO",""); + } + + if ( $res eq 'YES'){ + #examine system bootstrap files + $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$rc_dir; + } else { + $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$etc_dir."/rc.d"; + } else { + print "Failed to locate boostrap directory\n"; + print "wanrouter boot scripts will not be installed\n"; + return 1; + } + } + + if($zaptel_installed==$TRUE){ + print "Verifying Zaptel boot scripts..."; + #find zaptel start scripts + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; + $res=`$command`; + if ($res =~ /.*S(\d+)zaptel/){ + $zaptel_start_level=$1; + print "Enabled (level:$zaptel_start_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_start_level"; + } + } else { + print "Not installed\n"; + $zaptel_start_level=0; + } + + #find zaptel stop scripts + print "Verifying Zaptel shutdown scripts..."; + $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find ".$rc_dir."/rc6.d/*zaptel"; + $res=`$command`; + if ($res =~ /.*K(\d+)zaptel/){ + $zaptel_stop_level=$1; + print "Enabled (level:$zaptel_stop_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; + } + } else { + print "Not installed\n"; + $zaptel_stop_level=0; + } + if ($zaptel_start_level != 0){ + $wanrouter_start_level=$zaptel_start_level-1; + } + if ($zaptel_stop_level != 0){ + $wanrouter_stop_level=$zaptel_stop_level-1; + } + } + + my $wanrouter_start_script=''; + if($wanrouter_start_level < 10){ + $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; + } else { + $wanrouter_start_script="S".$wanrouter_start_level.$script_name; + } + my $wanrouter_stop_script=''; + if($wanrouter_stop_level < 10){ + $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; + } else { + $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; + } + + $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; + if(system($command) !=0){ + $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; + if(system($command) !=0){ + print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; + print "$script_name boot scripts not installed\n"; + return 1; } + } + print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; + if(system($command) !=0){ + print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; + print "$script_name start scripts not installed\n"; + return 1; + } + } + + print "Enabling $script_name shutdown scripts ...(level:$wanrouter_stop_level)\n"; + @run_levels= ("0","1","6"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; + if(system($command) !=0){ + print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; + print "$script_name stop scripts not installed\n"; + return 1; + } + } + + if($num_bri_devices != 0){ + #smg_ctrl must start after network + print "Verifying Network boot scripts..."; + $command="find $rc_dir/rc".$current_run_level.".d/*network >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*network"; + $res=`$command`; + if ($res =~ /.*S(\d+)network/){ + $network_start_level=$1; + print "Enabled (level:$network_start_level)\n"; + } else { + print "\nfailed to parse network boot level, assuming $network_start_level"; + } + } else { + print "Not installed\n"; + $network_start_level=0; + } + if ($network_start_level != 0 && $network_start_level > $zaptel_start_level){ + $smg_ctrl_start_level=$network_start_level+1; + print "Enabling smg_ctrl start scripts...(level:$smg_ctrl_start_level)\n"; + $command="install -D -m 755 /usr/sbin/smg_ctrl $rc_dir/init.d/smg_ctrl"; + if(system($command) !=0){ + print "Failed to install smg_ctrl start scripts to $rc_dir/init.d/smg_ctrl"; + print "smg_ctrl start scripts not installed"; + return 1; + } + my $smg_ctrl_start_script=''; + if($smg_ctrl_start_level < 10){ + $smg_ctrl_start_script="S0".$smg_ctrl_start_level."smg_ctrl"; + } else { + $smg_ctrl_start_script="S".$smg_ctrl_start_level."smg_ctrl"; + } + print "Enabling smg_ctrl boot scripts ...(level:$smg_ctrl_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/smg_ctrl ".$rc_dir."/rc".$run_level.".d/".$smg_ctrl_start_script; + if(system($command) !=0){ + print "Failed to install smg_ctrl init script to $rc_dir/rc$run_level.d/$smg_ctrl_start_script\n"; + print "smg_ctrl start scripts not installed\n"; + return 1; + } + } + } + + } + + } + return 0; +} + + +sub config_ztcfg_start{ + if ($num_zaptel_config ==0 || $silent==$TRUE){ + return; + } + my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) != 0){ + #Zaptel init scripts not installed, prompt for wanpipe_zaptel_start_script + print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + exec_command("cp -f $current_dir/templates/zaptel_cfg_script $wanpipe_conf_dir/scripts/start"); + } + } +} + +sub config_smg_ctrl_start{ + if($num_bri_devices == 0){ + return; + } + my $res; + if($silent==$FALSE) { + print ("Would you like smg_ctrl to start/stop on wanrouter start?\n"); + $res = &prompt_user_list("YES","NO",""); + } else { + $res = "YES"; + } + + if ($res = "YES"){ + #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite + my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; + } else { + $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; + } + + if (system($command) == 0){ + print "smgbri start script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + + $command="cp -f ".$current_dir."/templates/smgbri_stop_script ".$wanpipe_conf_dir."/scripts/stop"; + if (system($command) == 0){ + print "smgbri stop script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + } +} + +sub check_zaptel{ + if ($modprobe_list =~ /zaptel.ko/){ + $zaptel_installed=$TRUE; + } +} + +sub apply_changes{ + my $asterisk_command=''; + my $bri_command=''; + my $asterisk_restart=$FALSE; + my $res=''; + + if($silent==$FALSE) {system('clear')}; + + if($silent==$TRUE){ + $res="Stop now"; + }elsif($is_tdm_api==$TRUE){ + print "\n Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", + "Do not save cfg: Exit", + ""); + }else{ + print "\nZaptel and Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", + "Save cfg: Restart Asterisk & Wanpipe when convenient", + "Save cfg: Stop Asterisk & Wanpipe now", + "Save cfg: Stop Asterisk & Wanpipe when convenient", + "Do not save cfg: Exit", + ""); + } + + + if ($res =~ m/Exit/){ + print "No changes made to your configuration files\n"; + exit 0; + } + if ($res =~ m/now/){ + $asterisk_command='stop now'; + } else { + $asterisk_command='stop when convenient'; + } + + if ($res =~ m/Restart/){ + $asterisk_restart=$TRUE; + } else { + $asterisk_restart=$FALSE; + } + + if ($is_trixbox==$TRUE){ + exec_command("amportal stop"); + unload_zap_modules(); + } elsif ($is_tdm_api==$FALSE ){ + if (`(pidof asterisk)` != 0 ){ + print "\nStopping Asterisk...\n"; + exec_command("asterisk -rx \"$asterisk_command\""); + sleep 2; + while (`(pidof asterisk)` != 0 ){ + if ($asterisk_command eq "stop now"){ + print "Failed to stop asterisk using command: \'$asterisk_command\' \n"; + my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes"); + my $res=&prompt_user_list(@options,""); + + if ( $res =~ m/Force Stop/){ + execute_command("kill -KILL \$(pidof asterisk)"); + } elsif ( $res =~ m/Exit/ ){ + exit(1); + } else { + print "Waiting for asterisk to stop...\n"; + sleep 5; + exec_command("asterisk -rx \"$asterisk_command\""); + } + } else { + #stop when convenient option was selected + print "Waiting for asterisk to stop...\n"; + sleep 3; + } + } + + + + + + }else { + print "\nAsterisk is not running...\n"; + } + + } + + if($num_bri_devices != 0){ + exec_command("/usr/sbin/smg_ctrl stop"); + } + + print "\nStopping Wanpipe...\n"; + exec_command("wanrouter stop all"); + + if ($zaptel_installed==$TRUE){ + if($is_tdm_api==$FALSE){ + print "\nUnloading Zaptel modules...\n"; + unload_zap_modules(); + } + } + + print "\nRemoving old configuration files...\n"; + + exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); + + gen_wanrouter_rc(); + + print "\nCopying new Wanpipe configuration files...\n"; + copy_config_files(); + if($num_bri_devices != 0){ + print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; + exec_command("cp -f $bri_conf_file $bri_conf_file_t"); + exec_command("cp -f $woomera_conf_file $woomera_conf_file_t"); + } + + if ($zaptel_installed==$TRUE){ + if($config_zaptel==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; + exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); + } + } + } + + if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; + exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); + } + } + + if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ + print "\nStarting Wanpipe...\n"; + exec_command("wanrouter start"); + + if($num_bri_devices != 0){ + print "Loading SMG BRI...\n"; + sleep 2; + exec_command("/usr/sbin/smg_ctrl start"); + } + + if ($num_zaptel_config != 0){ + print "Loading Zaptel...\n"; + sleep 2; + exec_command("ztcfg -v"); +# } + } + if ($is_trixbox==$TRUE){ + print "\nStarting Amportal...\n"; + exec_command("amportal start"); + sleep 2; + }elsif($config_zapata==$TRUE){ + print "\nStarting Asterisk...\n"; + exec_command("asterisk"); + sleep 2; + + + if ($num_zaptel_config != 0){ + print "\nListing Asterisk channels...\n\n"; + exec_command("asterisk -rx \"zap show channels\""); + } + print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; + }else{ + } + } + print "\nWanrouter start complete...\n"; +} + + + +sub save_debug_info{ + my $version=`wanrouter version`; + chomp($version); + + my $uname=`uname -a`; + chomp($uname); + + my $issue=''; + + if ($os_type_list =~ m/Linux/){ + $issue=`cat $etc_dir/issue`; + chomp($issue); + } + + my $debug_info="\n"; + $debug_info.="===============================================================\n"; + $debug_info.=" SANGOMA DEBUG INFO FILE \n"; + $debug_info.=" Generated on $date \n"; + $debug_info.="===============================================================\n"; + + $debug_info.="\n\nwanrouter hwprobe\n"; + $debug_info.="@hwprobe\n"; + $debug_info.="\nwanrouter version\n"; + $debug_info.="$version\n"; + $debug_info.="\nKernel \"uname -a\"\n"; + $debug_info.="$uname\n"; + if ($os_type_list =~ m/Linux/){ + $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; + $debug_info.="$issue\n"; + } + $debug_info.="EOF\n"; + + open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; + print FH $debug_info; + close (FH); + exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); +} + +sub get_chan_no{ + my ($chan_name,$first_ch, $last_ch)=@_; + + my $res_ch=&prompt_user("\nInput the $chan_name channel for this span [$first_ch-$last_ch]\n"); + while(length($res_ch)==0 ||!($res_ch =~/(\d+)/) + || $res_ch<$first_ch || $res_ch>$last_ch){ + print "Invalid channel, must be between $first_ch and $last_ch\n"; + $res_ch=&prompt_user("Input the channel for this port[$first_ch-$last_ch]"); + } + return $res_ch; +} + +sub get_zapata_context{ + my ($card_model,$card_port)=@_; + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("Select dialplan context for AFT-A%s on port %s\n", $card_model, $card_port); + my $res = &prompt_user_list(@options,$def_zapata_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_zapata_context); + } + + $context=$res_context; + }elsif($res eq $def_zapata_context){ + $context=$def_zapata_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + if($#silent_zapata_contexts >= 0){ + $silent_zapata_context=pop(@silent_zapata_contexts); + } + $context=$silent_zapata_context; + } + $def_zapata_context=$context; + return $context; +} + + +sub get_woomera_context{ + my ($group,$card_model,$card_port,$bri_type)=@_; + + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($bri_type eq 'bri_nt'){ + @options = ("from-internal","Custom"); + } elsif ($bri_type eq 'bri_te'){ + @options = ("from-pstn","Custom"); + } + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("\nSelect dialplan context for group:%d\n", $group); + my $res = &prompt_user_list(@options,$def_woomera_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_woomera_context); + } + + $context=$res_context; + }elsif($res eq $def_woomera_context){ + $context=$def_woomera_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + if($#silent_woomera_contexts >= 0){ + $silent_woomera_context=pop(@silent_woomera_contexts); + } + $context=$silent_woomera_context; + } + $def_woomera_context=$context; + return $context; +} + + + +sub gen_wanrouter_rc{ + #update wanpipe startup sequence + my $rcfile=""; + if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { + open (FH,"$wanrouter_rc_template"); + } + while () { + $rcfile .= $_; + } + close (FH); + open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); + $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; + print FH $rcfile; + close (FH); +} + +sub prepare_files{ + + if ($is_trixbox==$TRUE){ + $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; + $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; + $zapata_conf_file_t="$asterisk_conf_dir/zapata-auto.conf"; + } + + if ($silent==$FALSE){ + if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ + print "Would you like to generate $zapata_conf_file_t\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $config_zapata = $FALSE; + } + } + } + +#remove temp files + my $tmp_cfg_dir="$current_dir"."/"."$cfg_dir"; + if ( -d "$current_dir"."/"."$cfg_dir") { + exec_command("rm -f $current_dir/$cfg_dir/*"); + } +#backup existing configuration files + if ( -f $zaptel_conf_file_t ) { + exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); + } + + if ( -f $zapata_conf_file_t ) { + exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); + } +} + +sub clean_files{ + exec_command("rm -rf $current_dir/$cfg_dir"); +} + + +sub write_zapata_conf{ + my $zp_file=""; + open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; + while () { + $zp_file .= $_; + } + close (FH); + + $zp_file.=$zapata_conf; + + open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; + print FH $zp_file; + close(FH); +} + +sub copy_config_files{ + my @wanpipe_files = split / /, $cfg_string; + exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc $wanpipe_conf_dir"); + foreach my $wanpipe_file (@wanpipe_files) { + exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf $wanpipe_conf_dir"); + } +} + +sub unload_zap_modules{ + my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); + foreach my $module (@modules_list) { + if ($modprobe_list =~ m/$module/){ + exec_command("$module_unload $module"); + } + } +} + +sub write_zaptel_conf{ + my $zp_file=""; + open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + $zp_file=$zp_file.$zaptel_conf; + open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; + print FH $zp_file; + close(FH); +} + +sub summary{ + if($devnum==1){ + if ($silent==$FALSE) {system('clear')}; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); + exit 0; + }else{ + if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ + write_zaptel_conf(); + } + if ($num_bri_devices != 0 ){ + write_bri_conf(); + write_woomera_conf(); + } + if ($num_zaptel_config != 0 && $config_zapata==$TRUE){ + write_zapata_conf(); + } + save_debug_info(); + if ($silent==$FALSE) {system('clear')}; + my $file_list = 1; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); + print(" $num_bri_devices_total ISDN BRI port(s) detected, $num_bri_devices configured\n"); + print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); + + print "\nConfigurator has created the following files:\n"; + print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; + $file_list++; + + if ($num_bri_devices != 0){ + print "\t$file_list. sangoma_brid config file $wanpipe_conf_dir/smg_bri\n"; + $file_list++; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; + } + + if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ + print "\n\nYour original configuration files will be saved to:\n"; + $file_list=1; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. $zaptel_conf_file_t.bak \n"; + $file_list++; + } + if ($num_zaptel_config !=0 && $config_zapata==$TRUE){ + print "\t$file_list. $zapata_conf_file_t.bak \n\n"; + } + + print "\nYour configuration has been saved in $debug_tarball.\n"; + print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } +} + + +sub exec_command{ + my @command = @_; + if (system(@command) != 0 ){ + print "Error executing command:\n@command\n\n"; + if($silent==$FALSE){ + print "Would you like to continue?\n"; + if(&prompt_user_list("No - exit", "YES", "No") eq 'YES'){ + return $?; + } else { + exit $?; + } + } + } + return $?; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "def=\"$defaultValue\": "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $defaultValue = @list[$#list]; + + my $i; + my $valid = 0; + for $i (0..$#list-1) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + my $list_sz = $#list; + print "[1-$list_sz"; + if ( ! $defaultValue eq ''){ + print ", ENTER=\'$defaultValue\']:"; + }else{ + print "]:"; + } + $| = 1; + $_ = ; + chomp; + if ( $_ eq '' & ! $defaultValue eq ''){ + print "\n"; + return $defaultValue; + } + + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $list_sz) { + print "\nError: Invalid option, input a value between 1 and $list_sz \n"; + } else { + print "\n"; + return @list[$1-1] ; + } + } else { + print "\nError: Invalid option, input an integer\n"; + } + } +} + +sub read_args { + my $arg_num; + foreach $arg_num (0 .. $#ARGV) { + $_ = $ARGV[$arg_num]; + if( /^--trixbox$/){ + $is_trixbox=$TRUE; + }elsif( /^--install_boot_script/){ + $boot_only=$TRUE; + }elsif ( /^--tdm_api/){ + $is_tdm_api=$TRUE; + }elsif ( /^--smg$/){ + $is_smg=$TRUE; + }elsif ( /^--no_boot$/){ + $no_boot=$TRUE; + }elsif ( /^--no_hwdtmf$/){ + $no_hwdtmf=$TRUE; + }elsif ( /^--silent$/){ + $silent=$TRUE; + }elsif ( /^--no-zapata$/){ + $config_zapata=$FALSE; + }elsif ( /^--no-zaptel$/){ + $config_zaptel=$FALSE; + }elsif ( $_ =~ /--zapata_context=(\w+)/){ + $silent_zapata_context=substr($_,length("--zapata_context=")); + push(@silent_zapata_contexts, $silent_zapata_context); + }elsif ( $_ =~ /--zapata_group=(\d+)/){ + $silent_zapata_group=$1; + push(@silent_zapata_groups, $silent_zapata_group); + }elsif ( $_ =~ /--woomera_context=(\w+)/){ + $silent_woomera_context=substr($_,length("--woomera_context=")); + push(@silent_woomera_contexts, $silent_woomera_context); + }elsif ( $_ =~ /--woomera_group=(\d+)/){ + $silent_woomera_group=$1; + push(@silent_woomera_groups, $silent_woomera_group); + }elsif ( $_ =~ /--fe_media=(\w+)/){ + $silent_femedia=$1; + if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ + printf("Invalid value for fe_media, should be T1/E1\n"); + exit(1); + } else { + push(@silent_femedias, $silent_femedia); + if($silent_femedia eq 'E1'){ + if(!($silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ + $silent_feframe='CRC4'; + } + if(!($silent_felcode eq 'HDB3' || $silent_felcode eq 'AMI')){ + $silent_felcode='HDB3'; + } + } + } + }elsif ( $_ =~ /--fractional_chans=(\d+)-(\d+)/ ){ + $silent_first_chan=$1; + $silent_last_chan=$2; + push(@silent_first_chans, $silent_first_chan); + push(@silent_last_chans, $silent_last_chan); + }elsif ( $_ =~ /--hw_dtmf=(\w+)/){ + $silent_hwdtmf=$1; + if(!($silent_hwdtmf eq 'YES' || $silent_hwdtmf eq 'NO')){ + printf("Invalid value for hw_dtmf, should be YES/NO\n"); + exit(1); + } else { + push(@silent_hwdtmfs, $silent_hwdtmf); + } + }elsif ( $_ =~ /--fe_lcode=(\w+)/){ + $silent_felcode=$1; + if(!($silent_felcode eq 'B8ZS' || $silent_felcode eq 'HDB3' || $silent_felcode eq 'AMI')){ + printf("Invalid value for fe_lcode, should be B8ZS/HDB3/AMI \n"); + exit(1); + } else { + push(@silent_felcodes, $silent_felcode); + } + }elsif ( $_ =~ /--fe_frame=(\w+)/){ + $silent_feframe=$1; + if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ + printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); + exit(1); + } else { + push(@silent_feframes, $silent_feframe); + } + }elsif ( $_ =~ /--tdm_law=(\w+)/){ + $silent_tdm_law=$1; + if(!($silent_tdm_law eq 'MULAW' || $silent_tdm_law eq 'ALAW')){ + printf("Invalid value for tdm_law, should be MULAW/ALAW\n"); + exit(1); + } else { + push(@silent_tdm_laws, $silent_tdm_law); + } + }elsif ( $_ =~ /--fe_clock=(\w+)/){ + $silent_feclock=$1; + if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ + printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); + exit(1); + } else { + push(@silent_feclocks, $silent_feclock); + } + }elsif ( $_ =~ /--signalling=(\w+)/){ + my $tmp_signalling=$1; + if ($tmp_signalling eq 'em'){ + $silent_signalling="E & M"; + }elsif ($tmp_signalling eq 'em_w'){ + $silent_signalling="E & M Wink"; + }elsif ($tmp_signalling eq 'pri_cpe'){ + $silent_signalling="PRI CPE"; + }elsif ($tmp_signalling eq 'pri_net'){ + $silent_signalling="PRI NET"; + }elsif ($tmp_signalling eq 'fxs_ls'){ + $silent_signalling="FXS - Loop Start"; + }elsif ($tmp_signalling eq 'fxs_gs'){ + $silent_signalling="FXS - Ground Start"; + }elsif ($tmp_signalling eq 'fxs_ks'){ + $silent_signalling="FXS - Kewl Start"; + }elsif ($tmp_signalling eq 'fxo_ls'){ + $silent_signalling="FXO - Loop Start"; + }elsif ($tmp_signalling eq 'fxo_gs'){ + $silent_signalling="FXO - Ground Start"; + }elsif ($tmp_signalling eq 'fxo_ks'){ + $silent_signalling="FXO - Kewl Start"; + }else{ + printf("Invalid option for --signalling, options are\n"); + printf("\t pri_cpe/pri_net/em/em_w\n"); + printf("\t fxo_ls/fxo_gs/fxo_ks\n"); + printf("\t fxs_ls/fxs_gs/fxs_ks\n"); + exit(1); + } + + push(@silent_signallings, $silent_signalling); + + }elsif ( $_ =~ /--pri_switchtype=(\w+)/){ + my $tmp_switchtype=$1; + if ($tmp_switchtype eq 'national'){ + $silent_pri_switchtype="national" + }elsif ($tmp_switchtype eq 'dms100'){ + $silent_pri_switchtype="dms100" + }elsif ($tmp_switchtype eq '4ess'){ + $silent_pri_switchtype="4ess" + }elsif ($tmp_switchtype eq '5ess'){ + $silent_pri_switchtype="5ess" + }elsif ($tmp_switchtype eq 'euroisdn'){ + $silent_pri_switchtype="euroisdn" + }elsif ($tmp_switchtype eq 'ni1'){ + $silent_pri_switchtype="ni1" + }elsif ($tmp_switchtype eq 'qsig'){ + $silent_pri_switchtype="qsig" + } else { + printf("Invalid option for --pri_switchtype, options are\n"); + printf("\t national/dms100/4ess/5ess/euroisdn/ni1/qsig"); + exit(1); + } + push(@silent_pri_switchtypes, $silent_pri_switchtype); + }elsif ( $_ =~ /--conf_dir=(.*)/){ + $etc_dir=$1; + if (! -d $etc_dir){ + printf("Error: directory $1 does not exist\n"); + exit(1); + } + }else { + printf("Error: Unrecognized parameter \"$_\" \n"); + exit(1); + + } + } + @silent_femedias = reverse(@silent_femedias); + @silent_feframes = reverse(@silent_feframes); + @silent_felcodes = reverse(@silent_felcodes); + @silent_tdm_laws = reverse(@silent_tdm_laws); + @silent_feclocks = reverse(@silent_feclocks); + @silent_signallings = reverse(@silent_signallings); + @silent_pri_switchtypes = reverse(@silent_pri_switchtypes); + @silent_zapata_contexts = reverse(@silent_zapata_contexts); + @silent_woomera_contexts = reverse(@silent_woomera_contexts); + @silent_zapata_groups = reverse(@silent_zapata_groups); + @silent_hwdtmfs = reverse(@silent_hwdtmfs); + @silent_first_chans = reverse(@silent_first_chans); + @silent_last_chans = reverse(@silent_last_chans); + + if ($is_trixbox==$TRUE){ + print "\nGenerating configuration files for Trixbox\n"; + } + if ($is_smg==$TRUE){ + print "\nGenerating configuration files for Sangoma Media Gateway\n"; + } + if ($is_tdm_api==$TRUE){ + $config_zapata = $FALSE; + } + +} + +#------------------------------BRI FUNCTIONS------------------------------------# +sub get_bri_country { + $def_bri_country = "europe"; + return $def_bri_country; +} + +sub get_woomera_group{ + if($silent==$TRUE){ + if($#silent_woomera_groups >= 0){ + $silent_woomera_group=pop(@silent_woomera_groups); + } + return $silent_woomera_group; + } + + my $group; + my $res_group=&prompt_user("\nInput the group for this port\n",$def_woomera_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ + print "Invalid group, input an integer greater than 0\n"; + $res_group=&prompt_user("Input the group for this port",$def_woomera_group); + } + $group=$res_group; + $def_woomera_group=$group; + return $def_woomera_group; +} + + +sub get_bri_operator { +#warning returning ETSI + $def_bri_operator = "etsi"; + return $def_bri_operator; + + + + my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", + "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", + "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); + + my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); + + my $res = &prompt_user_list(@options,$def_switchtype); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_operator=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + +sub write_bri_conf{ + my $bri_file=""; + open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; + while () { + $bri_file .= $_; + } + close (FH); + $bri_file=$bri_file.$bri_conf; + open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; + print FH $bri_file; + close(FH); +} + +sub write_woomera_conf{ + my $woomera_file=""; + open(FH, "$woomera_conf_template") or die "cannot open $woomera_conf_template"; + while () { + $woomera_file .= $_; + } + close (FH); + $woomera_file=$woomera_file.$woomera_conf; + open(FH, ">$woomera_conf_file") or die "cannot open $woomera_conf_file"; + print FH $woomera_file; + close(FH); +} + + +sub get_bri_conn_type{ + my ($port)=@_; + + if($silent==$TRUE){ + if($#silent_bri_conn_types >= 0){ + $silent_bri_conn_type=pop(@silent_bri_conn_types); + } + return $silent_bri_conn_type; + } + printf("\nSelect connection type for port %d\n", $port); + my $conn_type; + + my @options = ( "Point to multipoint", "Point to point"); + my @options_val = ("point_to_multipoint", "point_to_point"); + + my $res = &prompt_user_list(@options,$def_bri_conn_type); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_conn_type=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid BRI connection type\n"; + exit 1; +} + + + + +sub config_bri{ + if($is_smg!=$TRUE && $is_trixbox==$FALSE){ + return; + } + my $a50x; + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring ISDN BRI cards [A500]\n"; + print "------------------------------------\n"; + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ + $skip_card=$FALSE; + if ($1 eq '500'){ + my $card = eval {new Card(); } or die ($@); + + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + + my $hwec=0; + if($6 gt 0){ + $hwec=1; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + + if ($card->card_model eq '500'){ + $num_bri_devices_total++; + if($5 eq '1'){ + $bri_device_has_master_clock=$FALSE; + } + if ($silent==$FALSE) { + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + } + +select_bri_option: + if($silent==$FALSE){ + print "\nWould you like to configure AFT-A$1 port $5 on slot:$3 bus:$4\n"; + my @options=("YES", "NO", "Exit"); + $def_bri_option=&prompt_user_list(@options,$def_bri_option); + } else { + $def_bri_option="YES"; + } + + + if($def_bri_option eq 'YES'){ + $skip_card=$FALSE; + $bri_conf.="\n;Sangoma AFT-A$1 port $5 [slot:$3 bus:$4 span:$current_tdmapi_span]"; + }elsif($def_bri_option eq 'NO'){ + $skip_card=$TRUE; + }else{ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } else { + goto select_bri_option; + } + } + if ($skip_card==$FALSE){ + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + $a50x = eval {new A50x(); } or die ($@); + $a50x->card($card); + $a50x->fe_line($5); + $devnum++; + $num_bri_devices++; + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + }else{ + print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; + prompt_user("Press any key to continue"); + } + + } + } + }elsif (($dev =~ /(\d+):NT/ | + $dev =~ /(\d+):TE/ )& + $skip_card==$FALSE ){ + + + my $context=""; + my $group=""; + my $bri_pos=$a50x->card->tdmv_span_no; + + printf("\nConfiguring port %d on AFT-A%d [slot:%d bus:%d span:%d]\n", $a50x->fe_line(), $a50x->card->card_model(), $a50x->card->pci_slot(), $a50x->card->pci_bus(), $current_tdmapi_span-1); + my $conn_type=get_bri_conn_type($a50x->fe_line()); + my $country=get_bri_country(); + my $operator=get_bri_operator(); + if($is_trixbox==$TRUE && $silent==$FALSE){ + if ( $dev =~ /(\d+):NT/ ){ + $context="from-internal"; + $group=1; + } else { + $context="from-zaptel"; + $group=2; + } + } else { + $group=get_woomera_group(); + #if a context has already been assigned to this group, do not prompt for options + foreach my $f_group (@woomera_groups) { + if($f_group eq $group){ + $context="WOOMERA_NO_CONFIG"; + } + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + if ( $dev =~ /(\d+):NT/ ){ + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_nt'); + } else { + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_te'); + } + push(@woomera_groups, $group); + + } + } + $a50x->gen_wanpipe_conf(); + if ( $dev =~ /(\d+):NT/ ){ + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_nt", $group, $country, $operator, $conn_type); + } else { + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + $woomera_conf.=$a50x->gen_woomera_conf($group, $context); + } + + } + } + if($num_bri_devices_total!=0){ + print("\nISBN BRI card configuration complete\n\n"); + } else { + print("\nNo Sangoma ISDN BRI cards detected\n\n"); + } + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } +} + + + + + +#------------------------------T1/E1 FUNCTIONS------------------------------------# + +sub get_te_ref_clock{ + my @list_normal_clocks=@_; + my @f_list_normal_clocks; + my $f_port; + foreach my $port (@list_normal_clocks) { + if ($port eq '0'){ + $f_port = "Free run"; + } else { + $f_port = "Port ".$port; + } + push(@f_list_normal_clocks, $f_port); + } + + my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); + my $i; + + for $i (0..$#f_list_normal_clocks){ + if ( $res eq @f_list_normal_clocks[$i] ){ + return @list_normal_clocks[$i]; + } + } + + print "Internal error: Invalid reference clock\n"; + exit 1; + +} + + +sub prompt_user_hw_dchan{ + my ($card_model, $port, $port_femedia) = @_; + my $res_dchan=''; + my $dchan; + + printf("Hardware HDLC can be performed on the data channel.\n"); +prompt_hw_dchan: + my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); + while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ + print "Invalid channel, input an integer (0 for unused).\n"; + $res_dchan=&prompt_user("Select the data channel","0"); + } + if ( $res_dchan < 0){ + printf("Error: channel cannot have negative value\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ( $port_femedia eq 'T1' && $res_dchan > 24){ + printf("Error: only 24 channels available on T1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + }elsif ($port_femedia eq 'E1' && $res_dchan > 31){ + printf("Error: only 31 channels available on E1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ($res_dchan == 0){ + printf("HW HDLC channel not used\n"); + }else{ + printf("HW HDLC channel set to:%d\n", $res_dchan); + } + return $res_dchan; +} + + +sub get_zapata_group{ + my ($card_model,$card_port,$context)=@_; + my $group=''; + if($silent==$TRUE){ + if($#silent_zapata_groups >= 0){ + $silent_zapata_group=pop(@silent_zapata_groups); + } + $silent_zapata_group = + return $silent_zapata_group; + } + if($is_trixbox==$TRUE){ + if($context eq "from-zaptel"){ + $group=0; + return $group; + }elsif($context eq "from-internal"){ + $group=1; + return $group; + }else{ + print "Internal error:invalid group for Trixbox\n"; + } + }else{ + if($context eq "from-pstn"){ + $group=0; + }elsif($context eq "from-internal"){ + $group=1; + }else{ + my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)){ + print "Invalid group, input an integer.\n"; + $res_group=&prompt_user("Input the group for this port",$def_zapata_group); + } + $group=$res_group; + $def_zapata_group=$group; + } + } + + return $group; +} + + + +sub prompt_hw_dtmf { +#HW DTMF not supported in the 3.2 drivers +# return "NO"; + if( $no_hwdtmf == $TRUE){ + return "NO"; + } + print("Would you like to enable hardware DTMF detection?\n"); + my @options = ("YES","NO"); + $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); + return $def_hw_dtmf; +} + +sub prompt_tdm_law { + print("Which codec will be used?\n"); + my @options = ("MULAW - North America","ALAW - Europe"); + my @options_val = ("MULAW", "ALAW"); + my $res = &prompt_user_list(@options, $def_tdm_law); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_tdm_law=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid TDM LAW type\n"; + exit 1; +} + + +sub get_pri_switchtype { + my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); + my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); + my $res = &prompt_user_list(@options,$def_switchtype); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_switchtype=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + + +sub gen_ss7_voicechans{ + my @ss7_array = @_; + my $T1CHANS = pop(@ss7_array); + my $count = @ss7_array; + my $output =''; + my $chan_in = 1; + my $chan_de = 0; + my $flag = 0; + my $i = 0; + my $j = 0; + + while($i < $count){ + $j = $i + 1; + if ($ss7_array[$i] > 2 && $i == 0){ + $chan_de = $ss7_array[$i] - 1; + $output .= "1-$chan_de"; + $flag = 1; + }elsif ($ss7_array[$i] == 2 && $i == 0){ + $output .= "1"; + $flag = 1; + } + + if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ + goto Incrementing; + }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ + goto Incrementing; + } + + if ($i < ($count-1)){ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < ($ss7_array[$j]-1)){ + $chan_de = $ss7_array[$j] - 1; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$chan_in"; + }else{ + $output .= "$chan_in"; + $flag = 1; + } + } + }else{ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < $T1CHANS){ + $chan_de = $T1CHANS; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$T1CHANS"; + }else{ + $output .= "$T1CHANS"; + $flag = 1; + } + } + } + +Incrementing: + $i++; + } + return $output; +} + +sub prompt_user_ss7_chans{ + my @ss7_string = @_; + my $def_ss7_group_chan = ''; + + my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + +CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ + print("ERROR: Invalid channel number, input an integer only.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); +} + if ($line_media eq 'T1'){ + while ($ss7_group_chan>24 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 24 channels in T1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +}elsif ($line_media eq 'E1'){ + while ($ss7_group_chan>31 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 31 channels in E1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +} + return $ss7_group_chan; +} + + + + + + +sub config_t1e1{ + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + print "---------------------------------------------\n"; + print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; + print "---------------------------------------------\n"; + + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + + if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ + #do not count analog devices + $num_digital_devices_total++; + } + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + + my $hwec=0; + if ( $dev =~ /HWEC=(\d+)/){ + if($1 gt 0){ + $hwec=1; + } + } + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + my $port=$6; + if ($6 eq 'PRI') { + $port=$5; + } + + if ( $card->card_model eq '101' | + $card->card_model eq '102' | + $card->card_model eq '104' | + $card->card_model eq '108' ){ + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ + print "A$1 detected on slot:$3 bus:$4\n"; + $device_has_normal_clock=$FALSE; + @device_normal_clocks = ("0"); + } + $first_cfg=0; + if($silent==$FALSE){ + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; + print "$msg"; + print "-----------------------------------------------------------\n"; + } + my $fe_media = ''; + if ($silent==$TRUE){ + if($#silent_femedias >= 0){ + $silent_femedia=pop(@silent_femedias); + } + + $fe_media = $silent_femedia; + } else { + printf ("\nSelect media type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + my @options = ("T1", "E1", "Unused","Exit"); + $fe_media = prompt_user_list( @options, $def_femedia); + } + + if ( $fe_media eq 'Exit'){ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } + }elsif ( $fe_media eq 'Unused'){ + $def_femedia=$fe_media; + my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; + print "$msg"; + prompt_user("Press any key to continue"); + }else{ + if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ + $device_has_hwec=$TRUE; + } + + $def_femedia=$fe_media; + $cfg_string.="wanpipe$devnum "; + my $a10x; + + if ($1 !~ m/104/ && $2 !~ m/SH/) { + $a10x = eval {new A10u(); } or die ($@); + $a10x->card($card); + if ($5 eq "A") { + $a10x->fe_line("1"); + } else { + $a10x->fe_line("2"); + } + } else { + $a10x = eval {new A10x(); } or die ($@); + if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + $a10x->card($card); + $a10x->fe_line($6); + } + + $card->first_chan($current_zap_channel); + $a10x->fe_media($fe_media); + if ( $fe_media eq 'T1' ){ + $max_chans = 24; + $line_media = 'T1'; + + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + + + if ($silent==$FALSE){ + printf ("Configuring port %s on AFT-A%s as: %s, coding:%s, framing:%s.\n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe, + $port); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("B8ZS", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("ESF", "D4"); + $def_feframe= &prompt_user_list(@options, $def_feframe); + } + + + } else { + if($#silent_felcodes >= 0){ + $silent_felcode=pop(@silent_felcodes); + } + $def_felcode=$silent_felcode; + + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + + if($#silent_feframes >= 0){ + $silent_feframe=pop(@silent_feframes); + } + $def_feframe=$silent_feframe; + + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + } + + + }else{ #fe_media = E1 + $max_chans = 31; + $line_media = 'E1'; + + + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("HDB3", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("CRC4", "NCRC4","UNFRAMED"); + $def_feframe = &prompt_user_list(@options, $def_feframe); + +# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); +# my @options = ("CCS - Clear channel signalling ", "CAS"); +# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); + + } + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode on AFT-A%s port %s\n",$card->card_model, $port); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + } else { + $def_te_sig_mode="CAS"; + } + + + } else { + if($#silent_felcodes >= 0){ + $silent_felcode=pop(@silent_felcodes); + } + $def_felcode=$silent_felcode; + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + + if($#silent_feframes >= 0){ + $silent_feframe=pop(@silent_feframes); + } + $def_feframe=$silent_feframe; + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + } + + + } + $a10x->fe_lcode($def_felcode); + $a10x->fe_frame($def_feframe); + if($silent==$FALSE){ + my @options = ("NORMAL", "MASTER"); + printf ("Select clock for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_feclock=&prompt_user_list(@options, $def_feclock); + } else { + if($#silent_feclocks >= 0){ + $silent_feclock=pop(@silent_feclocks); + } + $def_feclock=$silent_feclock; + } + + $a10x->fe_clock($def_feclock); + if ( $def_feclock eq 'NORMAL') { + $device_has_normal_clock=$TRUE; + push(@device_normal_clocks, $a10x->fe_line); + } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ + printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", + $card->card_model, + $port, + $card->pci_slot, + $card->pci_bus); + printf(" Free run: Use internal oscillator on card [default] \n"); + printf(" Port N: Sync with clock from port N \n\n"); + + printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); + $a10x->te_ref_clock($def_te_ref_clock); + } + + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if($#silent_hwdtmfs >= 0){ + $silent_hwdtmf=pop(@silent_hwdtmfs); + } + if ($card->hwec_mode eq "YES" && $no_hwdtmf==$FALSE){ + $card->hw_dtmf($silent_hwdtmf); + } else { + $card->hw_dtmf("NO"); + } + } + + + + my @options=""; + if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_smg==$TRUE && $zaptel_installed==$FALSE){ + @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_tdm_api==$TRUE){ + $def_signalling="TDM API"; + } else { + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); + } + if ($silent==$FALSE){ + if( $is_tdm_api == $FALSE){ + printf ("Select signalling type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_signalling=&prompt_user_list(@options,$def_signalling); + } + } else { + if($#silent_signallings >= 0){ + $silent_signalling=pop(@silent_signallings); + } + $def_signalling=$silent_signalling; + } + $a10x->signalling($def_signalling); + + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + + } else { + $def_te_sig_mode="CAS"; + } + $a10x->te_sig_mode($def_te_sig_mode); + + my $ss7_chan; + my $ss7_group_start; + my $ss7_group_end; + my @ss7_chan_array; + my @ss7_sorted; + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_option(1); + print("Choose an option below to configure SS7 signalling channels:\n"); + my @options =("Configure individual signalling channels(e.g #1,#10)", + "Configure consecutive signalling channels(e.g #1-#16)"); + my $res = &prompt_user_list(@options, ""); + if ( $res eq 'Configure individual signalling channels(e.g #1,#10)'){ + goto SS7CHAN; + while (1){ + print("\nAny other SS7 signalling channel to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7CHAN: + $ss7_chan = prompt_user_ss7_chans('Specify the channel for SS7 signalling(24 for T1? 16 for E1?)'); + push(@ss7_chan_array, $ss7_chan); + $ss7_array_length = @ss7_chan_array; + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + }else{ + goto SS7GROUP; + while(1){ + print("\nAny other SS7 consecutive signalling channels to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7GROUP: + $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); + $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); + if ($ss7_group_start > $ss7_group_end){ + print("The starting channel number is bigger than the ending one!\n"); + goto SS7GROUP; + } + my $i = 0; + for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ + push(@ss7_chan_array, $i); + my @remove_duplicate; + @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); + $ss7_array_length = @ss7_chan_array; + + if ($ss7_array_length > $max_chans){ + print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); + + @ss7_chan_array = (); + goto SS7GROUP; + } + } + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + } + +ENDSS7CONFIG: + + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); + my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); + $ss7_tdmvoicechans = $ss7_voicechans; + + if ($ss7_voicechans =~ m/(\d+)/){ + $a10x->ss7_tdminterface($1); + } + + $a10x->ss7_tdmchan($ss7_voicechans); + + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + + #wanrouter start/stop for signalling span is controlled by ss7boxd + #$startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ + $a10x->ss7_option(2); + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + + }elsif ($a10x->signalling eq 'TDM API'){ + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); + } + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + }else{ + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $startup_string.="wanpipe$devnum "; + $current_zap_span++; + $current_zap_channel+=$max_chans; + } + + + + if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ + if ($silent==$FALSE && $config_zapata==$TRUE){ + printf ("Select switchtype for AFT-A%s on port %s \n", $card->card_model, $port); + $a10x->pri_switchtype(get_pri_switchtype()); + } else { + if($#silent_pri_switchtypes >= 0){ + $silent_pri_switchtype=pop(@silent_pri_switchtypes); + } + $def_feframe=$silent_feframe; + $a10x->pri_switchtype($silent_pri_switchtype); + } + } + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_subinterface(1); + $a10x->gen_wanpipe_ss7_subinterfaces(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(2); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + my $ss7_element; + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + + $a10x->gen_wanpipe_conf(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + }else{ + $a10x->gen_wanpipe_conf(); + } + + if ($is_smg==$TRUE && $config_zapata==$FALSE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' + | $a10x->signalling eq 'No Signaling (Voice Only)')){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ + + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + } + }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + if($silent==$FALSE){ + printf ("Configuring port %s on %s as a full %s\n", $a10x->fe_line(), $a10x->card->card_model(),$a10x->fe_media()); + my $res=&prompt_user_list("YES - Use all channels", "NO - Configure for fractional","YES"); + if ($res =~ m/NO/){ + my $max_chan=0; + if($a10x->fe_media eq 'T1'){ + $max_chan=24; + } else { + $max_chan=31; + } + my $first_chan = &get_chan_no("first",1,$max_chan-1); + my $last_chan = &get_chan_no("last",$first_chan+1,$max_chan); + + $a10x->frac_chan_first($first_chan); + $a10x->frac_chan_last($last_chan); + } + } else { + if($#silent_first_chans >= 0){ + $silent_first_chan = pop(@silent_first_chans); + $silent_last_chan = pop(@silent_last_chans); + } + + if($silent_first_chan != 0){ + $a10x->frac_chan_first($silent_first_chan); + $a10x->frac_chan_last($silent_last_chan); + } + } + + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + }elsif ($is_tdm_api == $FALSE){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + $devnum++; + $num_digital_devices++; + my $msg ="\nPort ".$port." on AFT-A".$card->card_model." configuration complete...\n"; + print "$msg"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + } + + + } + + } + } + if($num_digital_devices_total!=0){ + print("\nT1/E1 card configuration complete.\n"); + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + $first_cfg=0; + } +# close SCR; +} + + +#------------------------------ANALOG FUNCTIONS------------------------------------# + + +sub config_analog{ + if($is_tdm_api==$TRUE){ + return; + } + my $a20x; + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring analog cards [A200/A400]\n"; + print "------------------------------------\n"; + + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ + $skip_card=$FALSE; + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + my $hwec=$7; + if ($hwec==0){ + $card->hwec_mode('NO'); + } + else{ + $card->hwec_mode('YES'); + } + if ($card->card_model eq '200' | $card->card_model eq '400'){ + $num_analog_devices_total++; + if($silent==$FALSE) { + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + } + if($is_trixbox==$FALSE){ + if ($silent==$FALSE){ + print "\nWould you like to configure AFT-A$1 on slot:$3 bus:$4\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $skip_card=$TRUE; + } + } + } + if ($skip_card==$FALSE){ + + $a20x = eval {new A20x(); } or die ($@); + $a20x->card($card); + $card->first_chan($current_zap_channel); + + if ( $device_has_hwec==$TRUE && $silent==$FALSE){ + print "Will this AFT-A$1 synchronize with an existing Sangoma T1/E1 card?\n"; + print "\n WARNING: for hardware and firmware requirements, check:\n"; + print " http://wiki.sangoma.com/t1e1analogfaxing\n"; + + if (&prompt_user_list(("NO","YES","")) eq 'NO'){ + $a20x->rm_network_sync('NO'); + } else { + $a20x->rm_network_sync('YES'); + } + } + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + $a20x->tdm_law(&prompt_tdm_law()); + } else { + if($#silent_hwdtmfs >= 0){ + $silent_hwdtmf=pop(@silent_hwdtmfs); + } + + if ($card->hwec_mode eq "YES" && $no_hwdtmf==$FALSE){ + $card->hw_dtmf($silent_hwdtmf); + } else { + $card->hw_dtmf("NO"); + } + + if($#silent_tdm_laws >= 0){ + $silent_tdm_law=pop(@silent_tdm_laws); + } + + $a20x->tdm_law($silent_tdm_law); + } + + + print "A$1 configured on slot:$3 bus:$4 span:$current_zap_span\n"; + $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + $current_zap_channel+=24; + my $i; + $devnum++; + $num_analog_devices++; + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + $a20x->gen_wanpipe_conf(); + + }else{ + print "A$1 on slot:$3 bus:$4 not configured\n"; + prompt_user("Press any key to continue"); + } + } + }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + if($silent==$TRUE){ + if($#silent_zapata_contexts >= 0){ + $silent_zapata_context=pop(@silent_zapata_contexts); + } + $a20x->card->zap_context($silent_zapata_context); + } else { + $a20x->card->zap_context("from-internal"); + } + $a20x->card->zap_group("1"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); + }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + if($silent==$TRUE){ + if($#silent_zapata_contexts >= 0){ + $silent_zapata_context=pop(@silent_zapata_contexts); + } + $a20x->card->zap_context($silent_zapata_context); + } else { + $a20x->card->zap_context("from-zaptel"); + } + $a20x->card->zap_group("0"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); + } + } + if($num_analog_devices_total!=0){ + print("\nAnalog card configuration complete\n\n"); + if( $silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } + +} + diff --git a/util/wancfg_zaptel/A10u.pm b/util/wancfg_zaptel/A10u.pm index 0029d88..019fca2 100644 --- a/util/wancfg_zaptel/A10u.pm +++ b/util/wancfg_zaptel/A10u.pm @@ -15,10 +15,13 @@ sub new { _fe_lcode => 'B8ZS', _fe_frame => 'ESF', _fe_clock => 'NORMAL', + _te_sig_mode => undef, _te_ref_clock => '0', _signalling => 'PRI_CPE', _pri_switchtype => 'national', _hw_dchan => '0', + _frac_chanfirst => '0', + _frac_chanlast => '0', _ss7_sigchan => undef, _ss7_option => undef, _ss7_tdmchan => undef, @@ -39,6 +42,17 @@ sub fe_line { $self->{_fe_line} = $fe_line if defined($fe_line); return $self->{_fe_line}; } +sub frac_chan_first { + my ( $self, $frac_chan_first ) = @_; + $self->{_frac_chan_first} = $frac_chan_first if defined($frac_chan_first); + return $self->{_frac_chan_first}; +} + +sub frac_chan_last { + my ( $self, $frac_chan_last ) = @_; + $self->{_frac_chan_last} = $frac_chan_last if defined($frac_chan_last); + return $self->{_frac_chan_last}; +} sub te_ref_clock { my ( $self, $te_ref_clock ) = @_; $self->{_te_ref_clock} = $te_ref_clock if defined($te_ref_clock); @@ -62,6 +76,13 @@ sub fe_lcode { return $self->{_fe_lcode}; } +sub te_sig_mode { + my ( $self, $te_sig_mode ) = @_; + $self->{_te_sig_mode} = $te_sig_mode if defined($te_sig_mode); + return $self->{_te_sig_mode}; +} + + sub fe_frame { my ( $self, $fe_frame ) = @_; $self->{_fe_frame} = $fe_frame if defined($fe_frame); @@ -159,9 +180,10 @@ sub print { sub gen_wanpipe_ss7_subinterfaces{ my ($self) = @_; - my $wanpipe_ss7_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->span_no.".conf"; + my $wanpipe_ss7_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; my $ss7_sigchan = $self->ss7_sigchan; - my $span_no = $self->card->span_no; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $device_no = $self->card->device_no; my $ss7_subinterface = $self->ss7_subinterface; my $ss7_tdmchan = $self->ss7_tdmchan; my $hwec_mode = $self->card->hwec_mode; @@ -176,10 +198,12 @@ sub gen_wanpipe_ss7_subinterfaces{ close (FH); open(FH, ">>$wanpipe_ss7_conf_file") or die "Cant open $wanpipe_ss7_conf_file"; - $wp_file =~ s/DEVNUM/$span_no/g; + $wp_file =~ s/DEVNUM/$device_no/g; $wp_file =~ s/SS7SIGCHAN/$ss7_sigchan/g; $wp_file =~ s/TDMVOICECHAN/$ss7_tdmchan/g; $wp_file =~ s/VOICEINTERFACE/$ss7_tdminterface/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + print FH $wp_file; close (FH); @@ -188,20 +212,24 @@ sub gen_wanpipe_ss7_subinterfaces{ sub gen_wanpipe_conf{ my ($self) = @_; my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm.a10u"; - my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->span_no.".conf"; - my $span_no = $self->card->span_no; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $device_no = $self->card->device_no; my $pci_slot = $self->card->pci_slot; my $pci_bus = $self->card->pci_bus; my $fe_media = $self->fe_media; my $fe_lcode = $self->fe_lcode; my $fe_frame = $self->fe_frame; my $fe_line = $self->fe_line; + my $te_sig_mode = $self->te_sig_mode; my $fe_clock = $self->fe_clock; my $ss7_option = $self->ss7_option; my $dchan = 0; my $fe_lbo; my $fe_cpu; + my $te_sig_mode_line=''; + if ($ss7_option == 1){ $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a10u/wanpipe.ss7.4"; @@ -220,6 +248,7 @@ sub gen_wanpipe_conf{ if ($self->fe_media eq 'T1'){ if ($self->signalling eq 'PRI CPE' | $self->signalling eq 'PRI NET'){ + $te_sig_mode = ''; $dchan = 24; } $fe_lbo='0DB'; @@ -229,6 +258,15 @@ sub gen_wanpipe_conf{ } $fe_lbo='120OH'; } + + + if ($te_sig_mode eq ''){ + $te_sig_mode_line=''; + }else{ + $te_sig_mode_line= 'TE_SIG_MODE = '.$te_sig_mode; + } + + open(FH, $wanpipe_conf_template ) or die "Cannot open $wanpipe_conf_template"; my $wp_file=''; while () { @@ -236,16 +274,18 @@ sub gen_wanpipe_conf{ } close (FH); open(FH, ">>$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; - $wp_file =~ s/DEVNUM/$span_no/g; + $wp_file =~ s/DEVNUM/$device_no/g; $wp_file =~ s/SLOTNUM/$pci_slot/g; $wp_file =~ s/BUSNUM/$pci_bus/g; $wp_file =~ s/FEMEDIA/$fe_media/g; $wp_file =~ s/FELCODE/$fe_lcode/g; + $wp_file =~ s/TESIGMODE/$te_sig_mode_line/g; $wp_file =~ s/FEFRAME/$fe_frame/g; $wp_file =~ s/FECPU/$fe_cpu/g; $wp_file =~ s/FECLOCK/$fe_clock/g; $wp_file =~ s/FELBO/$fe_lbo/g; $wp_file =~ s/TDMVDCHAN/$dchan/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; print FH $wp_file; close (FH); @@ -253,7 +293,7 @@ sub gen_wanpipe_conf{ # print "\n created $fname for A$card_model $devnum SLOT $slot BUS $bus HWEC $hwec_mode\n"; } sub gen_zaptel_conf{ - my ($self) = @_; + my ($self, $dchan_str) = @_; my $zap_lcode; my $zap_frame; my $zap_crc4; @@ -284,54 +324,103 @@ sub gen_zaptel_conf{ } my $zp_file=''; + $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + $zp_file.="span=".$self->card->tdmv_span_no.",0,0,".$zap_frame.",".$zap_lcode.$zap_crc4."\n"; + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + if ( $self->fe_media eq 'T1' ){ + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + if($self->frac_chan_last == 24){ + $self->frac_chan_last(23); + } + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="bchan=".$first_ch."-".$last_ch."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; + } else { + $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; + } + } else { + if($self->frac_chan_first() != 0){ + if($self->frac_chan_last() == 16){ + $self->frac_chan_last(15); + } + if($self->frac_chan_first() == 16){ + $self->frac_chan_first(17); + } + if($self->frac_chan_last() > 15){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + my $mid_ch1=$self->card->first_chan + 14; + my $mid_ch2=$self->card->first_chan + 16; + + $zp_file.="bchan=".$first_ch."-".$mid_ch1.",".$mid_ch2."-".$last_ch."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; + + } else { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="bchan=".$first_ch."-".$last_ch."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; + } + } else { + $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; + } + } + } else { + my $zap_signal; + if ( $self->signalling eq 'E & M' | $self->signalling eq 'E & M Wink' ){ + $zap_signal='e&m'; + } elsif ( $self->signalling eq 'FXS - Loop Start' ){ + $zap_signal='fxsls'; + } elsif ( $self->signalling eq 'FXS - Ground Start' ){ + $zap_signal='fxsgs'; + } elsif ( $self->signalling eq 'FXS - Kewl Start' ){ + $zap_signal='fxsks'; + } elsif ( $self->signalling eq 'FX0 - Loop Start' ){ + $zap_signal='fxols'; + } elsif ( $self->signalling eq 'FX0 - Ground Start' ){ + $zap_signal='fxogs'; + } elsif ( $self->signalling eq 'FX0 - Kewl Start' ){ + $zap_signal='fxoks'; + } else { + printf("Error: invalid signalling %s\n", $self->card->signalling); + } + + if ( $self->fe_media eq 'T1' ){ + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.=$zap_signal."=".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + } + } else { + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.=$zap_signal."=".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } + } + } + return $zp_file; - $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span: ".$self->card->span_no."]\n"; - $zp_file.="span=".$self->card->span_no.",0,0,".$zap_frame.",".$zap_lcode.$zap_crc4."\n"; - - if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ - if ( $self->fe_media eq 'T1' ){ - $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; - $zp_file.="dchan=".($self->card->first_chan+23)."\n"; - } else { - $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; - $zp_file.="dchan=".($self->card->first_chan+15)."\n"; - } - } else { - my $zap_signal; - if ( $self->signalling eq 'E & M' | $self->signalling eq 'E & M Wink' ){ - $zap_signal='e&m'; - } elsif ( $self->signalling eq 'FXS - Loop Start' ){ - $zap_signal='fxsls'; - } elsif ( $self->signalling eq 'FXS - Ground Start' ){ - $zap_signal='fxsgs'; - } elsif ( $self->signalling eq 'FXS - Kewl Start' ){ - $zap_signal='fxsks'; - } elsif ( $self->signalling eq 'FX0 - Loop Start' ){ - $zap_signal='fxols'; - } elsif ( $self->signalling eq 'FX0 - Ground Start' ){ - $zap_signal='fxogs'; - } elsif ( $self->signalling eq 'FX0 - Kewl Start' ){ - $zap_signal='fxoks'; - } else { - printf("Error: invalid signalling %s\n", $self->card->signalling); - } - - if ( $self->fe_media eq 'T1' ){ - $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; - } else { - $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; - } - } - return $zp_file; - } + sub gen_zapata_conf{ my ($self) = @_; my $zp_file=''; - $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span: ".$self->card->span_no."]\n"; - + + $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + +# $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span: ".$self->card->span_no."]\n"; + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ $zp_file.="switchtype=".$self->pri_switchtype."\n"; } @@ -364,21 +453,62 @@ sub gen_zapata_conf{ } if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ - if ( $self->fe_media eq 'T1' ){ - $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; - }else{ - $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; - } - } else { - if ( $self->fe_media eq 'T1' ){ - $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; - }else{ - $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; - } - - } - return $zp_file; - -} + if ( $self->fe_media eq 'T1' ){ + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + if($self->frac_chan_last == 24){ + $self->frac_chan_last(23); + } + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.="channel =>".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + } + }else{ + if($self->frac_chan_first() != 0){ + if($self->frac_chan_last() == 16){ + $self->frac_chan_last(15); + } + if($self->frac_chan_first() == 16){ + $self->frac_chan_first(17); + } + if($self->frac_chan_last() > 15){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + my $mid_ch1=$self->card->first_chan + 14; + my $mid_ch2=$self->card->first_chan + 16; + $zp_file.="channel =>".$first_ch."-".$mid_ch1.",".$mid_ch2."-".$last_ch."\n"; + } else { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } + } else { + $zp_file.="channel =>".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + } + } + } else { + if ( $self->fe_media eq 'T1' ){ + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + } + } else { + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } + } + } + return $zp_file; + +} + 1; diff --git a/util/wancfg_zaptel/A10x.pm b/util/wancfg_zaptel/A10x.pm index 9071845..fb27b97 100644 --- a/util/wancfg_zaptel/A10x.pm +++ b/util/wancfg_zaptel/A10x.pm @@ -16,10 +16,13 @@ sub new { _fe_lcode => 'B8ZS', _fe_frame => 'ESF', _fe_clock => 'NORMAL', + _te_sig_mode => undef, _te_ref_clock => '0', _signalling => 'PRI_CPE', _pri_switchtype => 'national', _hw_dchan => '0', + _frac_chanfirst => '0', + _frac_chanlast => '0', _ss7_sigchan => undef, _ss7_option => undef, _ss7_tdmchan => undef, @@ -41,6 +44,19 @@ sub fe_line { return $self->{_fe_line}; } +sub frac_chan_first { + my ( $self, $frac_chan_first ) = @_; + $self->{_frac_chan_first} = $frac_chan_first if defined($frac_chan_first); + return $self->{_frac_chan_first}; +} + +sub frac_chan_last { + my ( $self, $frac_chan_last ) = @_; + $self->{_frac_chan_last} = $frac_chan_last if defined($frac_chan_last); + return $self->{_frac_chan_last}; +} + + sub te_ref_clock { my ( $self, $te_ref_clock ) = @_; $self->{_te_ref_clock} = $te_ref_clock if defined($te_ref_clock); @@ -82,6 +98,12 @@ sub fe_clock { return $self->{_fe_clock}; } +sub te_sig_mode { + my ( $self, $te_sig_mode ) = @_; + $self->{_te_sig_mode} = $te_sig_mode if defined($te_sig_mode); + return $self->{_te_sig_mode}; +} + sub pri_switchtype { my ( $self, $pri_switchtype ) = @_; $self->{_pri_switchtype} = $pri_switchtype if defined($pri_switchtype); @@ -173,9 +195,10 @@ sub print { sub gen_wanpipe_ss7_subinterfaces{ my ($self) = @_; - my $wanpipe_ss7_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->span_no.".conf"; + my $wanpipe_ss7_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; my $ss7_sigchan = $self->ss7_sigchan; - my $span_no = $self->card->span_no; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $device_no = $self->card->device_no; my $ss7_subinterface = $self->ss7_subinterface; my $ss7_tdmchan = $self->ss7_tdmchan; my $hwec_mode = $self->card->hwec_mode; @@ -190,11 +213,12 @@ sub gen_wanpipe_ss7_subinterfaces{ close (FH); open(FH, ">>$wanpipe_ss7_conf_file") or die "Cant open $wanpipe_ss7_conf_file"; - $wp_file =~ s/DEVNUM/$span_no/g; + $wp_file =~ s/DEVNUM/$device_no/g; $wp_file =~ s/SS7SIGCHAN/$ss7_sigchan/g; $wp_file =~ s/TDMVOICECHAN/$ss7_tdmchan/g; $wp_file =~ s/HWECMODE/$hwec_mode/g; $wp_file =~ s/VOICEINTERFACE/$ss7_tdminterface/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; print FH $wp_file; close (FH); @@ -203,8 +227,9 @@ sub gen_wanpipe_ss7_subinterfaces{ sub gen_wanpipe_conf{ my ($self) = @_; my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm.a100"; - my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->span_no.".conf"; - my $span_no = $self->card->span_no; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + my $device_no = $self->card->device_no; + my $tdmv_span_no = $self->card->tdmv_span_no; my $pci_slot = $self->card->pci_slot; my $pci_bus = $self->card->pci_bus; my $fe_media = $self->fe_media; @@ -213,12 +238,14 @@ sub gen_wanpipe_conf{ my $fe_line = $self->fe_line; my $fe_clock = $self->fe_clock; my $te_ref_clock = $self->te_ref_clock; - my $te_sig_mode = ''; + my $te_sig_mode = $self->te_sig_mode; my $hwec_mode = $self->card->hwec_mode; + my $hw_dtmf = $self->card->hw_dtmf; my $ss7_option = $self->ss7_option; my $dchan = $self->hw_dchan; my $fe_lbo; + my $te_sig_mode_line=''; if ($ss7_option == 1){ $wanpipe_conf_template = $self->card->current_dir."/templates/ss7_a100/wanpipe.ss7.4"; @@ -230,22 +257,25 @@ sub gen_wanpipe_conf{ $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm_api.a100"; } - if ($self->fe_media eq 'T1'){ - if ($self->signalling eq 'PRI CPE' | $self->signalling eq 'PRI NET'){ + if ($self->signalling eq 'PRI CPE' | $self->signalling eq 'PRI NET' | $self->signalling eq 'SS7 - Sangoma Signal Media Gateway'){ $te_sig_mode = ''; $dchan = 24; } $fe_lbo='0DB'; }else{ - if ($self->signalling eq 'PRI CPE' | $self->signalling eq 'PRI NET' | $self->signalling eq 'SS7 - Sangoma Signal Media Gateway' | $self->signalling eq 'No Signaling (Voice Only)'){ + if ($self->signalling eq 'PRI CPE' | $self->signalling eq 'PRI NET' | $self->signalling eq 'SS7 - Sangoma Signal Media Gateway'){ $dchan = 16; - $te_sig_mode = 'TE_SIG_MODE = CCS'; - }else { - $te_sig_mode = 'TE_SIG_MODE = CAS'; } $fe_lbo='120OH'; } + + if ($te_sig_mode eq ''| $self->fe_media eq 'T1'){ + $te_sig_mode_line=''; + }else{ + $te_sig_mode_line= 'TE_SIG_MODE = '.$te_sig_mode; + } + open(FH, $wanpipe_conf_template) or die "Can't open $wanpipe_conf_template"; my $wp_file=''; while () { @@ -254,19 +284,21 @@ sub gen_wanpipe_conf{ close (FH); open(FH, ">>$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; - $wp_file =~ s/DEVNUM/$span_no/g; + $wp_file =~ s/DEVNUM/$device_no/g; $wp_file =~ s/SLOTNUM/$pci_slot/g; $wp_file =~ s/BUSNUM/$pci_bus/g; $wp_file =~ s/FEMEDIA/$fe_media/g; $wp_file =~ s/FELCODE/$fe_lcode/g; $wp_file =~ s/FEFRAME/$fe_frame/g; $wp_file =~ s/FELINE/$fe_line/g; - $wp_file =~ s/TESIGMODE/$te_sig_mode/g; + $wp_file =~ s/TESIGMODE/$te_sig_mode_line/g; $wp_file =~ s/FECLOCK/$fe_clock/g; $wp_file =~ s/TEREFCLOCK/$te_ref_clock/g; $wp_file =~ s/FELBO/$fe_lbo/g; $wp_file =~ s/TDMVDCHAN/$dchan/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; $wp_file =~ s/HWECMODE/$hwec_mode/g; + $wp_file =~ s/HWDTMF/$hw_dtmf/g; print FH $wp_file; close (FH); @@ -276,7 +308,7 @@ sub gen_wanpipe_conf{ sub gen_zaptel_conf{ - my ($self) = @_; + my ($self, $dchan_str) = @_; my $zap_lcode; my $zap_frame; my $zap_crc4; @@ -308,16 +340,50 @@ sub gen_zaptel_conf{ } - $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span: ".$self->card->span_no."]\n"; - $zp_file.="span=".$self->card->span_no.",0,0,".$zap_frame.",".$zap_lcode.$zap_crc4."\n"; + $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + $zp_file.="span=".$self->card->tdmv_span_no.",0,0,".$zap_frame.",".$zap_lcode.$zap_crc4."\n"; if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ if ( $self->fe_media eq 'T1' ){ - $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; - $zp_file.="dchan=".($self->card->first_chan+23)."\n"; + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + if($self->frac_chan_last == 24){ + $self->frac_chan_last(23); + } + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="bchan=".$first_ch."-".$last_ch."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; + } else { + $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; + } } else { - $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; - $zp_file.="dchan=".($self->card->first_chan+15)."\n"; + if($self->frac_chan_first() != 0){ + if($self->frac_chan_last() == 16){ + $self->frac_chan_last(15); + } + if($self->frac_chan_first() == 16){ + $self->frac_chan_first(17); + } + if($self->frac_chan_last() > 15){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + my $mid_ch1=$self->card->first_chan + 14; + my $mid_ch2=$self->card->first_chan + 16; + + $zp_file.="bchan=".$first_ch."-".$mid_ch1.",".$mid_ch2."-".$last_ch."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; + + } else { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="bchan=".$first_ch."-".$last_ch."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; + } + } else { + $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; + } } } else { my $zap_signal; @@ -340,9 +406,21 @@ sub gen_zaptel_conf{ } if ( $self->fe_media eq 'T1' ){ - $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.=$zap_signal."=".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + } } else { - $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.=$zap_signal."=".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } } } return $zp_file; @@ -353,8 +431,8 @@ sub gen_zapata_conf{ my ($self) = @_; my $zp_file=''; - $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span: ".$self->card->span_no."]\n"; - + $zp_file.="\n\;Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ $zp_file.="switchtype=".$self->pri_switchtype."\n"; } @@ -388,17 +466,58 @@ sub gen_zapata_conf{ if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ if ( $self->fe_media eq 'T1' ){ - $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + if($self->frac_chan_last == 24){ + $self->frac_chan_last(23); + } + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.="channel =>".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + } }else{ - $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + if($self->frac_chan_first() != 0){ + if($self->frac_chan_last() == 16){ + $self->frac_chan_last(15); + } + if($self->frac_chan_first() == 16){ + $self->frac_chan_first(17); + } + if($self->frac_chan_last() > 15){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + my $mid_ch1=$self->card->first_chan + 14; + my $mid_ch2=$self->card->first_chan + 16; + + $zp_file.="channel =>".$first_ch."-".$mid_ch1.",".$mid_ch2."-".$last_ch."\n"; + } else { + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } + } else { + $zp_file.="channel =>".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + } } } else { - if ( $self->fe_media eq 'T1' ){ - $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; - }else{ - $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + if ( $self->fe_media eq 'T1' ){ + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + } + } else { + if($self->frac_chan_first() != 0){ + my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; + my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; + $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; + } else { + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } } - } return $zp_file; diff --git a/util/wancfg_zaptel/A20x.pm b/util/wancfg_zaptel/A20x.pm index fcc0990..3870296 100644 --- a/util/wancfg_zaptel/A20x.pm +++ b/util/wancfg_zaptel/A20x.pm @@ -98,15 +98,19 @@ sub print { sub gen_wanpipe_conf{ my ($self) = @_; my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm.a200"; - my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->span_no.".conf"; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; - my $span_no = $self->card->span_no; + my $device_no = $self->card->device_no; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $pci_slot = $self->card->pci_slot; my $pci_bus = $self->card->pci_bus; my $tdm_law = $self->tdm_law; my $tdm_opermode = $self->tdm_opermode; my $rm_network_sync = $self->rm_network_sync; my $hwec_mode = $self->card->hwec_mode; + my $hw_dtmf = $self->card->hw_dtmf; + open(FH, $wanpipe_conf_template) or die "Can open $wanpipe_conf_template"; my $wp_file=''; @@ -115,14 +119,16 @@ sub gen_wanpipe_conf{ } close (FH); open(FH, ">$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; - $wp_file =~ s/DEVNUM/$span_no/g; + $wp_file =~ s/DEVNUM/$device_no/g; $wp_file =~ s/SLOTNUM/$pci_slot/g; $wp_file =~ s/BUSNUM/$pci_bus/g; $wp_file =~ s/TDM_LAW/$tdm_law/g; $wp_file =~ s/RMNETSYNC/$rm_network_sync/g; $wp_file =~ s/TDM_OPERMODE/$tdm_opermode/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; $wp_file =~ s/HWECMODE/$hwec_mode/g; - + $wp_file =~ s/HWDTMF/$hw_dtmf/g; + print FH $wp_file; close (FH); diff --git a/util/wancfg_zaptel/A50x.pm b/util/wancfg_zaptel/A50x.pm new file mode 100644 index 0000000..37b0e85 --- /dev/null +++ b/util/wancfg_zaptel/A50x.pm @@ -0,0 +1,173 @@ +#class A50x +#for A50x-sh series cards + +package A50x; +use Card; +use strict; + +#constructor +sub new { + my ($class) = @_; + my $self = { + _current_dir => undef, + _card => undef, + _fe_line => undef, + _fe_media => 'BRI', + _bri_clock_master => 'NO', + _bri_switchtype => 'etsi', + _bri_country => 'europe' + }; + bless $self, $class; + return $self; +} + +sub card { + my ( $self, $card ) = @_; + $self->{_card} = $card if defined($card); + return $self->{_card}; +} + +sub fe_line { + my ( $self, $fe_line ) = @_; + $self->{_fe_line} = $fe_line if defined($fe_line); + return $self->{_fe_line}; +} + +sub fe_media { + my ( $self, $fe_media ) = @_; + $self->{_fe_media} = $fe_media if defined($fe_media); + return $self->{_fe_media}; +} + +sub bri_clock_master { + my ( $self, $bri_clock_master ) = @_; + $self->{_bri_clock_master} = $bri_clock_master if defined($bri_clock_master); + return $self->{_bri_clock_master}; +} + +sub bri_switchtype { + my ( $self, $bri_switchtype ) = @_; + $self->{_bri_switchtype} = $bri_switchtype if defined($bri_switchtype); + return $self->{_bri_switchtype}; +} + + +sub current_dir { + my ( $self, $current_dir ) = @_; + $self->{_current_dir} = $current_dir if defined($current_dir); + return $self->{_current_dir}; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $i; + my $valid = 0; + for $i (0..$#list) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $#list+1) { + print "Invalid option: Value out of range \n"; + } else { + return $1-1 ; + } + } else { + print "Invalid option: Input an integer\n"; + } + } +} + +sub gen_wanpipe_conf{ + my ($self) = @_; + my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm_api.a500"; + my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf"; + + my $device_no = $self->card->device_no; + my $tdmv_span_no = $self->card->tdmv_span_no; + my $pci_slot = $self->card->pci_slot; + my $pci_bus = $self->card->pci_bus; + my $fe_media = $self->fe_media; + my $fe_line = $self->fe_line; + my $hwec_mode = $self->card->hwec_mode; + my $bri_clock_master = $self->bri_clock_master; + + + open(FH, $wanpipe_conf_template) or die "Can't open $wanpipe_conf_template"; + my $wp_file=''; + while () { + $wp_file .= $_; + } + close (FH); + + open(FH, ">>$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file"; + $wp_file =~ s/DEVNUM/$device_no/g; + $wp_file =~ s/SLOTNUM/$pci_slot/g; + $wp_file =~ s/BUSNUM/$pci_bus/g; + $wp_file =~ s/FEMEDIA/$fe_media/g; + $wp_file =~ s/FELINE/$fe_line/g; + $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; + $wp_file =~ s/HWECMODE/$hwec_mode/g; + $wp_file =~ s/RMBRICLOCKMASTER/$bri_clock_master/g; + + print FH $wp_file; + close (FH); + +} + + +sub gen_bri_conf{ + my ($self, $span, $type, $group, $country, $operator, $conn_type) = @_; + my $bri_file=''; + + $bri_file.="\n"; + $bri_file.="group=$group\n"; + $bri_file.="country=$country\n"; + $bri_file.="operator=$operator\n"; + $bri_file.="connection_type=$conn_type\n"; + + + if ( $type eq 'bri_nt'){ + $bri_file.="signalling=bri_nt\n"; + }else{ + $bri_file.="signalling=bri_te\n"; + } + + $bri_file.="spans=$span\n"; + + return $bri_file; +} + + +sub gen_woomera_conf{ + my ($self, $group, $context) = @_; + my $woomera_file=''; + + $woomera_file.="\n"; + $woomera_file.="context=$context\n"; + $woomera_file.="group=$group\n"; + return $woomera_file; +} + + +1; diff --git a/util/wancfg_zaptel/Card.pm b/util/wancfg_zaptel/Card.pm index e21db20..7203bed 100644 --- a/util/wancfg_zaptel/Card.pm +++ b/util/wancfg_zaptel/Card.pm @@ -7,12 +7,14 @@ sub new { my $self = { _current_dir => undef, _cfg_dir => undef, - _span_no => undef, + _device_no => undef, + _tdmv_span_no => undef, _card_model => undef, _pci_slot => undef, _pci_bus => undef, _fe_cpu => 'A', _hwec_mode => 'NO', + _hw_dtmf => 'NO', _first_chan => '0', _zap_context => undef, _zap_group => undef @@ -21,10 +23,16 @@ sub new { return $self; } -sub span_no { - my ( $self, $span_no ) = @_; - $self->{_span_no} = $span_no if defined($span_no); - return $self->{_span_no}; +sub device_no { + my ( $self, $device_no ) = @_; + $self->{_device_no} = $device_no if defined($device_no); + return $self->{_device_no}; +} + +sub tdmv_span_no { + my ( $self, $tdmv_span_no ) = @_; + $self->{_tdmv_span_no} = $tdmv_span_no if defined($tdmv_span_no); + return $self->{_tdmv_span_no}; } sub card_model { @@ -57,6 +65,12 @@ sub hwec_mode { return $self->{_hwec_mode}; } +sub hw_dtmf { + my ( $self, $hw_dtmf ) = @_; + $self->{_hw_dtmf} = $hw_dtmf if defined($hw_dtmf); + return $self->{_hw_dtmf}; +} + sub signalling { my ( $self, $signalling ) = @_; $self->{_signalling} = $signalling if defined($signalling); diff --git a/util/wancfg_zaptel/Makefile b/util/wancfg_zaptel/Makefile index 93a4417..50e5b7c 100644 --- a/util/wancfg_zaptel/Makefile +++ b/util/wancfg_zaptel/Makefile @@ -7,7 +7,7 @@ ####### MACROS ############################################################### # Build options. -WZDIR=usr/local/sbin/wancfg_zaptel +WZDIR=/etc/wanpipe/wancfg_zaptel WAN_VIRTUAL= all: diff --git a/util/wancfg_zaptel/install.sh b/util/wancfg_zaptel/install.sh index 8bcbe66..951ae7d 100755 --- a/util/wancfg_zaptel/install.sh +++ b/util/wancfg_zaptel/install.sh @@ -16,14 +16,21 @@ fi mkdir -p $WAN_VIRTUAL/$WZDIR cp -rf . $WAN_VIRTUAL/$WZDIR -cp -rf setup-sangoma $WAN_VIRTUAL/usr/local/sbin -chmod 755 $WAN_VIRTUAL/usr/local/sbin/setup-sangoma +install -D -m 755 setup-sangoma $WAN_VIRTUAL/usr/local/sbin/setup-sangoma +install -D -m 755 wancfg_zaptel $WAN_VIRTUAL/usr/sbin/wancfg_zaptel +install -D -m 755 wancfg_smg $WAN_VIRTUAL/usr/sbin/wancfg_smg +install -D -m 755 wancfg_tdmapi $WAN_VIRTUAL/usr/sbin/wancfg_tdmapi -cp -rf wancfg_zaptel $WAN_VIRTUAL/usr/sbin -chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_zaptel -cp -rf wancfg_smg $WAN_VIRTUAL/usr/sbin -chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_smg +#cp -rf setup-sangoma $WAN_VIRTUAL/usr/local/sbin +#chmod 755 $WAN_VIRTUAL/usr/local/sbin/setup-sangoma -cp -rf wancfg_tdmapi $WAN_VIRTUAL/usr/sbin -chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_tdmapi + +#cp -rf wancfg_zaptel $WAN_VIRTUAL/usr/sbin +#chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_zaptel + +#cp -rf wancfg_smg $WAN_VIRTUAL/usr/sbin +#chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_smg + +#cp -rf wancfg_tdmapi $WAN_VIRTUAL/usr/sbin +#chmod 755 $WAN_VIRTUAL/usr/sbin/wancfg_tdmapi diff --git a/util/wancfg_zaptel/setup-sangoma b/util/wancfg_zaptel/setup-sangoma index 6a7cae6..1690edd 100755 --- a/util/wancfg_zaptel/setup-sangoma +++ b/util/wancfg_zaptel/setup-sangoma @@ -1,5 +1,5 @@ #!/bin/sh home=`pwd` -cd /usr/local/sbin/wancfg_zaptel +cd /etc/wanpipe/wancfg_zaptel ./wancfg_zaptel.pl --trixbox cd $home diff --git a/util/wancfg_zaptel/templates/smg_bri.conf b/util/wancfg_zaptel/templates/smg_bri.conf new file mode 100644 index 0000000..22d1cdb --- /dev/null +++ b/util/wancfg_zaptel/templates/smg_bri.conf @@ -0,0 +1,113 @@ +;Country: +;possible values (default:europe): +;australia, austria, belgium, canada, chile, denmark, europe, finland, france, +;germany, hong_kong, india, irlande, israel, italy, japan, korea, luxembourg, +;netherlands, new_zealand, norway, portugal, singapore, south_africa, spain, +;sweden, switzerland, taiwan, uk, usa, ussr +; +;country=europe + +;Verbose: +;Increase level to at least 5 when debugging protocol related issues +;possible values (default:1): +;1-10 +; +;verbose=3 + +;Protocol capture: +;Enable/disable BRI protocol stack capture +;possible values (default:no): +;yes/no +; +;prot_capture=no + +;D-channel log: +;Enable/disable d-channel log +;Log file stored in /var/log/bri_log_span_# +;possible values (default:no) +;yes/no +; +;dchan_log=no + +;Dialplan: +;Some switches require the 'type of number' network specific facility IE to be set. +;This affects outgoing calls only. +;possible values (default:unknown): +;unknown +;national +;international +;network_specific +;subscriber +;abbreviated +; +;dialplan=unknown + +;Prefix: +;Prepends digits for calling number on incoming calls based on +;"type of number" network specific facility IE. +;This affects incoming calls only. +; +;unknown_prefix= +;national_prefix= +;international_prefix= +;networkspf_prefix= +;subscriber_prefix= +;abbreviated_prefix= +; +;international_prefix=001 + +;Local Number (MSN): +;Used in point to multipoint configurations +;Protocol will only answer if called number = local number +; +;local_number=12356789 + +;Incoming calls behaviour +;See http://wiki.sangoma.com/BriAdvancedOptions for details +;in_calls_behaviour=VOICE_ALERT_RQ + +;Outgoing calls behaviour +;See http://wiki.sangoma.com/BriAdvancedOptions for details +;out_calls_behaviour=USER_SENDING_COMPLETE + +;General calls behaviour +;See http://wiki.sangoma.com/BriAdvancedOptions for details +;gen_calls_behaviour=CHAN_ALLOC_LOWEST + +;Number of incoming digits +;Number of digits to route call if "Sending complete" bit is not set +;This only applies to incoming calls in overlap dial mode only +;possible values(default:8) +;1-31 +; +;num_digits=8 + +;Signalling: +;Signalling method. +;possible values (default:bri_te) +;bri_te :Customer side +;bri_nt ;Network side (Telco) + +;Connection: +;Connection type +;Most telcos use point_to_multipoint. +;set to point_to_point when connecting a NT port to ISDN BRI phone +;possible values (default:point_to_multipoint) +;point_to_point +;point_to_multipoint +; +;connection_type=point_to_multipoint + +;Group: +;Group assigned for outgoing calls +;possible values (default:1) +;1-63 +; +;group=1 + +;Spans +;Physical spans +;spans=1,2,3,4 + +verbose=3 +prot_capture=yes diff --git a/util/wancfg_zaptel/templates/smgbri_start_script b/util/wancfg_zaptel/templates/smgbri_start_script new file mode 100644 index 0000000..1fab1fe --- /dev/null +++ b/util/wancfg_zaptel/templates/smgbri_start_script @@ -0,0 +1,24 @@ +#!/bin/sh +cnt=0 +max_delay=30 +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/wptdm_s1c1 ]; then + break; + fi + + echo "Waiting for TDM API device /dev/wp_tdm ($i/$max_delay)..." + sleep 2 +done + +if [ ! -e /dev/wptdm_s1c1 ]; then + echo + echo "Error: Sangoma TDM API device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +smg_ctrl start diff --git a/util/wancfg_zaptel/templates/smgbri_start_script_addon b/util/wancfg_zaptel/templates/smgbri_start_script_addon new file mode 100644 index 0000000..ad57d2b --- /dev/null +++ b/util/wancfg_zaptel/templates/smgbri_start_script_addon @@ -0,0 +1,24 @@ + +cnt=0 +max_delay=30 +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/wptdm_s1c1 ]; then + break; + fi + + echo "Waiting for TDM API device /dev/wp_tdm ($i/$max_delay)..." + sleep 2 +done + +if [ ! -e /dev/wptdm_s1c1 ]; then + echo + echo "Error: Sangoma TDM API device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +smg_ctrl start diff --git a/util/wancfg_zaptel/templates/smgbri_stop_script b/util/wancfg_zaptel/templates/smgbri_stop_script new file mode 100644 index 0000000..daed6de --- /dev/null +++ b/util/wancfg_zaptel/templates/smgbri_stop_script @@ -0,0 +1,2 @@ +#!/bin/sh +smg_ctrl stop diff --git a/util/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.5 b/util/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.5 index 97a7338..e71c84e 100644 --- a/util/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.5 +++ b/util/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.5 @@ -1,4 +1,4 @@ -TDMV_SPAN = DEVNUM +TDMV_SPAN = TDMVSPANNO TDMV_DCHAN = 0 [wDEVNUMgVOICEINTERFACE] diff --git a/util/wancfg_zaptel/templates/ss7_a100/wanpipe.tdmvoiceapi.a100 b/util/wancfg_zaptel/templates/ss7_a100/wanpipe.tdmvoiceapi.a100 index c23a5be..52155c4 100644 --- a/util/wancfg_zaptel/templates/ss7_a100/wanpipe.tdmvoiceapi.a100 +++ b/util/wancfg_zaptel/templates/ss7_a100/wanpipe.tdmvoiceapi.a100 @@ -32,7 +32,7 @@ FE_LCODE = FELCODE FE_FRAME = FEFRAME FE_LINE = FELINE TE_CLOCK = FECLOCK -TE_REF_CLOCK = TEREFCLOCK +TE_REF_CLOCK = TEREFCLOCK TESIGMODE TE_HIGHIMPEDANCE = NO LBO = FELBO @@ -41,12 +41,12 @@ MTU = 1500 UDPPORT = 9000 TTL = 255 IGNORE_FRONT_END = NO -TDMV_SPAN = DEVNUM +TDMV_SPAN = TDMVSPANNO TDMV_DCHAN = 0 +TDMV_HW_DTMF = HWDTMF [wDEVNUMg1] ACTIVE_CH = ALL TDMV_ECHO_OFF = NO TDMV_HWEC = HWECMODE -MTU = 80 - +MTU = 80 diff --git a/util/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.5 b/util/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.5 index d9dad6a..1cf9c93 100644 --- a/util/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.5 +++ b/util/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.5 @@ -1,4 +1,4 @@ -TDMV_SPAN = DEVNUM +TDMV_SPAN = TDMVSPANNO TDMV_DCHAN = 0 [wDEVNUMgVOICEINTERFACE] diff --git a/util/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u b/util/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u index 11c3d5e..379d36e 100644 --- a/util/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u +++ b/util/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u @@ -40,7 +40,7 @@ MTU = 1500 UDPPORT = 9000 TTL = 255 IGNORE_FRONT_END = NO -TDMV_SPAN = DEVNUM +TDMV_SPAN = TDMVSPANNO TDMV_DCHAN = 0 [wDEVNUMg1] diff --git a/util/wancfg_zaptel/templates/wanpipe.tdm.a100 b/util/wancfg_zaptel/templates/wanpipe.tdm.a100 index 978269f..878ab14 100644 --- a/util/wancfg_zaptel/templates/wanpipe.tdm.a100 +++ b/util/wancfg_zaptel/templates/wanpipe.tdm.a100 @@ -41,8 +41,9 @@ MTU = 1500 UDPPORT = 9000 TTL = 255 IGNORE_FRONT_END = NO -TDMV_SPAN = DEVNUM +TDMV_SPAN = TDMVSPANNO TDMV_DCHAN = TDMVDCHAN +TDMV_HW_DTMF = HWDTMF [wDEVNUMg1] ACTIVE_CH = ALL diff --git a/util/wancfg_zaptel/templates/wanpipe.tdm.a10u b/util/wancfg_zaptel/templates/wanpipe.tdm.a10u index 73550c6..cabfe8e 100644 --- a/util/wancfg_zaptel/templates/wanpipe.tdm.a10u +++ b/util/wancfg_zaptel/templates/wanpipe.tdm.a10u @@ -33,6 +33,7 @@ FE_FRAME = FEFRAME FE_LINE = 1 TE_CLOCK = FECLOCK TE_REF_CLOCK = 0 +TESIGMODE TE_HIGHIMPEDANCE = NO LBO = FELBO FE_TXTRISTATE = NO @@ -40,7 +41,7 @@ MTU = 1500 UDPPORT = 9000 TTL = 255 IGNORE_FRONT_END = NO -TDMV_SPAN = DEVNUM +TDMV_SPAN = TDMVSPANNO TDMV_DCHAN = TDMVDCHAN [wDEVNUMg1] diff --git a/util/wancfg_zaptel/templates/wanpipe.tdm.a200 b/util/wancfg_zaptel/templates/wanpipe.tdm.a200 index 4a81a45..0f94c44 100644 --- a/util/wancfg_zaptel/templates/wanpipe.tdm.a200 +++ b/util/wancfg_zaptel/templates/wanpipe.tdm.a200 @@ -35,7 +35,8 @@ MTU = 1500 UDPPORT = 9000 TTL = 255 IGNORE_FRONT_END = NO -TDMV_SPAN = DEVNUM +TDMV_SPAN = TDMVSPANNO +TDMV_HW_DTMF = HWDTMF [wDEVNUMg1] ACTIVE_CH = ALL diff --git a/util/wancfg_zaptel/templates/wanpipe.tdm_api.a100 b/util/wancfg_zaptel/templates/wanpipe.tdm_api.a100 index 629ef55..66c68ad 100644 --- a/util/wancfg_zaptel/templates/wanpipe.tdm_api.a100 +++ b/util/wancfg_zaptel/templates/wanpipe.tdm_api.a100 @@ -41,10 +41,12 @@ MTU = 1500 UDPPORT = 9000 TTL = 255 IGNORE_FRONT_END = NO -TDMV_SPAN = DEVNUM +TDMV_SPAN = TDMVSPANNO TDMV_DCHAN = TDMVDCHAN +TDMV_HW_DTMF = HWDTMF [wDEVNUMg1] ACTIVE_CH = ALL TDMV_ECHO_OFF = NO TDMV_HWEC = HWECMODE +MTU = 80 diff --git a/util/wancfg_zaptel/templates/wanpipe.tdm_api.a500 b/util/wancfg_zaptel/templates/wanpipe.tdm_api.a500 new file mode 100755 index 0000000..4ff667f --- /dev/null +++ b/util/wancfg_zaptel/templates/wanpipe.tdm_api.a500 @@ -0,0 +1,45 @@ +#================================================ +# WANPIPE1 Configuration File +#================================================ +# +# Note: This file was generated automatically +# by /usr/local/sbin/setup-sangoma program. +# +# If you want to edit this file, it is +# recommended that you use wancfg program +# to do so. +#================================================ +# Sangoma Technologies Inc. +#================================================ + + + + +[devices] +wanpipeDEVNUM = WAN_AFT_ISDN_BRI, Comment + +[interfaces] +wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE_API, Comment + +[wanpipeDEVNUM] +CARD_TYPE = AFT +S514CPU = A +CommPort = PRI +AUTO_PCISLOT = NO +PCISLOT = SLOTNUM +PCIBUS = BUSNUM +FE_MEDIA = BRI +FE_LINE = FELINE +RM_BRI_CLOCK_MASTER = RMBRICLOCKMASTER +TDMV_LAW = ALAW +MTU = 1500 +UDPPORT = 9000 +TTL = 255 +IGNORE_FRONT_END = NO +TDMV_SPAN = TDMVSPANNO + +[wDEVNUMg1] +ACTIVE_CH = ALL +TDMV_ECHO_OFF = NO +TDMV_HWEC = HWECMODE +MTU = 80 diff --git a/util/wancfg_zaptel/templates/wanrouter.rc.template b/util/wancfg_zaptel/templates/wanrouter.rc.template new file mode 100644 index 0000000..0e8cf8e --- /dev/null +++ b/util/wancfg_zaptel/templates/wanrouter.rc.template @@ -0,0 +1,41 @@ +#!/bin/sh +# router.rc WAN router meta-configuration file. +# +# This file defines variables used by the router shell scripts +# and should be located in /etc/wanpipe directory. These are: +# +# ROUTER_BOOT = Boot flag (YES/NO). +# WAN_CONF_DIR = Where to put wanpipe config files. +# WAN_INTR_DIR = Where to put wanpipe interface files. +# WAN_LOG = Where to put start-up log file. +# WAN_LOCK = File used as a lock. +# WAN_LOCK_DIR = +# WAN_IP_FORWARD = Enable IP Forwarding on startup. +# WAN_DEVICES = Name of the wanpipe devices to be +# loaded on 'wanrouter start' +# (ex: "wanpipe1 wanpipe2 wanpipe3...") +# +# Note: Name of wanpipe devices correspond +# to the configuration files in +# WANPIPE_CONF_DIR directory: +# (ex. /etc/wanpipe/wanpipe1.conf ) +# +# Note: This file is 'executed' by the shell script, so +# the usual shell syntax must be observed. +ROUTER_BOOT=YES +WAN_CONF_DIR=/etc/wanpipe +WAN_INTR_DIR=/etc/wanpipe/interfaces +WAN_LOG=/var/log/wanrouter +WAN_LOCK=/var/lock/subsys/wanrouter +WAN_LOCK_DIR=/var/lock/subsys +WAN_IP_FORWARD=NO +NEW_IF_TYPE=NO +WAN_LIB_DIR=/etc/wanpipe/lib +WAN_ADSL_LIST=/etc/wanpipe/wan_adsl.list +WAN_ANNEXG_LOAD=NO +WAN_LIP_LOAD=YES +WAN_DYN_WANCONFIG=NO +WAN_SCRIPTS_DIR=/etc/wanpipe/scripts +WAN_FIRMWARE_DIR=/etc/wanpipe/firmware +WAN_DEVICES_REV_STOP_ORDER=YES +WAN_DEVICES="WPSTARTUP" diff --git a/util/wancfg_zaptel/templates/wanrouter.rc.template.FreeBSD b/util/wancfg_zaptel/templates/wanrouter.rc.template.FreeBSD new file mode 100644 index 0000000..a9f6188 --- /dev/null +++ b/util/wancfg_zaptel/templates/wanrouter.rc.template.FreeBSD @@ -0,0 +1,34 @@ + +# /usr/local/etc/wanpipe/wanrouter.rc WAN router meta-configuration file. +# +# This file defines variables used by the router shell scripts +# and should be located in /usr/local/etc/wanpipe directory. These are: +# +# ROUTER_BOOT= Boot flag (YES/NO). +# WAN_CONF_DIR= Directory of wanpipe config files. +# WAN_INTR_DIR= Where to put wanpipe interface files. +# WAN_FIRMWARE_DIR= Where to put protocol firmware files. +# WAN_LOG= Where to put start-up log file. +# WAN_LOCK_DIR= Directory of wanpipe device lock files. +# WAN_DEVICES= Name of the wanpipe devices to be +# loaded on 'wanrouter start' +# (ex: "wanpipe1 wanpipe2 wanpipe3...") +# +# Note: Name of wanpipe devices correspond +# to the configuration files in +# /usr/local/etc/wanpipe directory: +# (ex. /usr/local/etc/wanpipe/wanpipe1.conf ) +# +# Note: This file is 'executed' by the shell script, so +# the usual shell syntax must be observed. +ROUTER_BOOT=YES +WAN_BIN_DIR=/usr/local/sbin +WAN_CONF_DIR=/usr/local/etc/wanpipe +WAN_INTR_DIR=/usr/local/etc/wanpipe/interfaces +WAN_MODULE_DIR=/usr/local/lib/wanpipe +WAN_FIRMWARE_DIR=/usr/local/etc/wanpipe/firmware +WAN_LOG=/var/log/wanrouter +WAN_LOCK_DIR=/var/lock +WAN_LIB_DIR=/usr/local/etc/wanpipe/lib +WAN_ADSL_LIST=/usr/local/etc/wanpipe/wan_adsl.list +WAN_DEVICES="WPSTARTUP" diff --git a/util/wancfg_zaptel/templates/woomera.conf b/util/wancfg_zaptel/templates/woomera.conf new file mode 100644 index 0000000..9fe5c8e --- /dev/null +++ b/util/wancfg_zaptel/templates/woomera.conf @@ -0,0 +1,12 @@ +[settings] +debug=2 + +[default] +host=localhost +port=42420 +audio_ip=127.0.0.1 +default_context=sangoma +debug=2 +dtmf_enable=1 +jb_enable=0 +progress_enable=0 diff --git a/util/wancfg_zaptel/templates/zaptel_cfg_script b/util/wancfg_zaptel/templates/zaptel_cfg_script new file mode 100644 index 0000000..9793904 --- /dev/null +++ b/util/wancfg_zaptel/templates/zaptel_cfg_script @@ -0,0 +1,29 @@ +#!/bin/sh +#Make sure that udev/devfs zaptel device +#has come up. +cnt=0 +max_delay=30 + + +echo -n "Waiting for zaptel device /dev/zap ..." +for ((i=0;i<$max_delay;i++)) +do + if [ -e /dev/zap ]; then + break; + fi + echo -n "." + sleep 2 +done +echo " " +if [ ! -e /dev/zap ]; then + echo + echo "Error: Zaptel device failed to come up"; + echo "Possible Cause: UDEV not installed!"; + echo + exit 1 +fi + +sleep 1 + +ztcfg -v + diff --git a/util/wancfg_zaptel/templates/zaptel_cfg_script.FreeBSD b/util/wancfg_zaptel/templates/zaptel_cfg_script.FreeBSD new file mode 100644 index 0000000..6f2deaf --- /dev/null +++ b/util/wancfg_zaptel/templates/zaptel_cfg_script.FreeBSD @@ -0,0 +1,6 @@ +#!/bin/sh + +sleep 1 + +ztcfg -v + diff --git a/util/wancfg_zaptel/wancfg_smg b/util/wancfg_zaptel/wancfg_smg old mode 100755 new mode 100644 index 1d52cde..34d4049 --- a/util/wancfg_zaptel/wancfg_smg +++ b/util/wancfg_zaptel/wancfg_smg @@ -1,7 +1,45 @@ #!/bin/sh home=`pwd` -cd /usr/local/sbin/wancfg_zaptel -./wancfg_zaptel.pl --smg cd $home -~ +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --smg --conf_dir=$WAN_BASE +cd $home diff --git a/util/wancfg_zaptel/wancfg_tdmapi b/util/wancfg_zaptel/wancfg_tdmapi index 71d99c4..b48085d 100755 --- a/util/wancfg_zaptel/wancfg_tdmapi +++ b/util/wancfg_zaptel/wancfg_tdmapi @@ -1,5 +1,45 @@ #!/bin/sh home=`pwd` -cd /usr/local/sbin/wancfg_zaptel -./wancfg_zaptel.pl --tdm_api +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --tdm_api --conf_dir=$WAN_BASE cd $home diff --git a/util/wancfg_zaptel/wancfg_zaptel b/util/wancfg_zaptel/wancfg_zaptel index 2384548..239eaca 100755 --- a/util/wancfg_zaptel/wancfg_zaptel +++ b/util/wancfg_zaptel/wancfg_zaptel @@ -1,5 +1,51 @@ #!/bin/sh home=`pwd` -cd /usr/local/sbin/wancfg_zaptel -./wancfg_zaptel.pl +cd $home + +read_meta_conf () +{ + + if [ $ostype = "Linux" ]; then + WAN_BASE=/etc + WAN_HOME=$WAN_BASE/wanpipe + META_CONF=$WAN_BASE/wanpipe/wanrouter.rc + elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then + WAN_BASE=/usr/local/etc + WAN_HOME=$WAN_BASE/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + WAN_HOME=${wanrouter_rc_file%/*} + fi + META_CONF=$wanrouter_rc_file + fi + + # Read meta-configuration file. + if [ -f $META_CONF ] + then . $META_CONF + else + return 1 + fi + return 0 +} + +ostype=`sysctl -a |grep ostype` +ostype=`echo $ostype | sed 's/.* //'` + +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + +read_meta_conf +if [ $? -ne 0 ]; then + echo "ERROR: Failed to find Wanpipe meta config file!" + exit 1 +fi + +cd ${WAN_HOME}/wancfg_zaptel +./wancfg_zaptel.pl --conf_dir=$WAN_BASE $ARGS cd $home diff --git a/util/wancfg_zaptel/wancfg_zaptel.pl b/util/wancfg_zaptel/wancfg_zaptel.pl index 7f1477e..3b885b9 100755 --- a/util/wancfg_zaptel/wancfg_zaptel.pl +++ b/util/wancfg_zaptel/wancfg_zaptel.pl @@ -9,25 +9,31 @@ # as published by the Free Software Foundation; either version # 2 of the License, or (at your option) any later version. # ---------------------------------------------------------------------------- -# Jul 20, 2007 David Yat Sin silent option -# Jun 13, 2007 Yuan Shen SS7 support -# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major -# changes to script. -# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl -# Jan 5, 2007 David Yat Sin v2.1 fix for analog cards inserted in wrong -# context -# Dec 12, 2006 David Yat Sin v2.0 support for T1/E1 cards -# Oct 13, 2006 David Yat Sin Added --opermode and --law option -# Oct 12, 2006 David Yat Sin Initial version +# Jan 02 2008 2.11 David Yat Sin Support for per span configuration in silent mode +# Jan 02 2008 2.10 David Yat Sin Added option for BRI master clock +# Dec 15 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 +# Nov 29 2007 2.8 David Yat Sin Support for BRI cards on Trixbox +# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option +# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode +# Jul 20, 2007 2.5 David Yat Sin silent option +# Jun 13, 2007 Yuan Shen SS7 support +# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major +# changes to script. +# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl +# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong +# context +# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards +# Oct 13, 2006 David Yat Sin Added --opermode and --law option +# Oct 12, 2006 David Yat Sin Initial version # ============================================================================ system('clear'); -print "\n###################################################################"; -print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; -print "\n# v2.5 #"; -print "\n# Sangoma Technologies Inc. #"; -print "\n# Copyright(c) 2007. #"; -print "\n###################################################################\n\n"; +print "\n#############################################i##########################"; +print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI/BOOT Configuration Script #"; +print "\n# v2.10 #"; +print "\n# Sangoma Technologies Inc. #"; +print "\n# Copyright(c) 2007. #"; +print "\n########################################################################\n\n"; use strict; #use warnings; @@ -36,51 +42,145 @@ use Card; use A10x; use A10u; use A20x; +use A50x; + my $FALSE = 1; my $TRUE = 0; +my $zaptelprobe=' '; +my $etc_dir=""; +my $include_dir=""; +my $module_list=""; +my $module_load=""; +my $module_unload=""; +my $os_type_name=""; +my $dchan_str="dchan"; + +my $os_type_list=`sysctl -a |grep ostype`; +if ($os_type_list =~ m/Linux/){ + $os_type_name="Linux"; + $etc_dir="/etc"; + $module_load="modprobe"; + $module_unload="modprobe -r"; + $module_list="modprobe -l"; + $include_dir="/usr/include"; +}elsif ($os_type_list =~ m/FreeBSD/){ + $os_type_name="FreeBSD"; + $etc_dir="/usr/local/etc"; + $module_load="kldload"; + $module_unload="kldunload"; + $module_list="kldstat"; +}else{ + print("Failed to determine OS type\n"); + print("Exiting...\n"); + exit(1); +} + + +my $no_boot=$FALSE; +my $boot_only=$FALSE; +#HW DTMF NOT SUPPORTED in 3.2 drivers +#my $no_hwdtmf=$FALSE; +my $no_hwdtmf=$TRUE; my $startup_string=""; +my $cfg_string=""; +my $first_cfg=1; my $zaptel_conf=""; my $zapata_conf=""; +my $bri_conf=""; +my $woomera_conf=""; my $devnum=1; +my $current_zap_span=1; +my $current_tdmapi_span=1; +#my $current_bri_span=1; my $current_zap_channel=1; my $num_analog_devices=0; my $num_analog_devices_total=0; +my $num_bri_devices=0; +my $num_bri_devices_total=0; my $num_digital_devices=0; my $num_digital_devices_total=0; -my $num_non_ss7_config=0; my $num_ss7_config=0; -my $asked_autozapata=0; +my $num_zaptel_config=0; my $line_media=''; my $max_chans=0; my $ss7_tdmvoicechans=''; my $ss7_array_length=0; + + my $device_has_hwec=$FALSE; my $device_has_normal_clock=$FALSE; my @device_normal_clocks=("0"); +my @woomera_groups=("0"); +my $bri_device_has_master_clock=$FALSE; my $is_tdm_api=$FALSE; my $def_femedia=''; my $def_feframe=''; my $def_feclock=''; +my $def_bri_option=''; my $def_signalling=''; my $def_switchtype=''; my $def_zapata_context=''; +my $def_woomera_context=''; my $def_zapata_group=''; my $def_te_ref_clock=''; my $def_tdmv_dchan=0; +my $def_woomera_group=''; +my $def_felcode=''; +my $def_feframe=''; +my $def_te_sig_mode=''; +my $def_hw_dtmf="YES"; +my $def_tdm_law=''; + + +my @silent_femedias; +my @silent_feframes; +my @silent_felcodes; +my @silent_tdm_laws; +my @silent_feclocks; +my @silent_signallings; +my @silent_pri_switchtypes; +my @silent_zapata_contexts; +my @silent_woomera_contexts; +my @silent_zapata_groups; +my @silent_bri_conn_types; +my @silent_woomera_groups; +my @silent_hwdtmfs; +my @silent_first_chans; +my @silent_last_chans; + + +my $silent_hwdtmf; my $silent_femedia="T1"; my $silent_feframe="ESF"; -my $silent_feframe_e1="CRC4"; +#my $silent_feframe_e1="CRC4"; + +my $silent_felcode="B8ZS"; +my $silent_tdm_law="MULAW"; + + my $silent_feclock="NORMAL"; my $silent_signalling="PRI CPE"; -my $silent_switchtype="National"; +my $silent_pri_switchtype="national"; my $silent_zapata_context="from-pstn"; +my $silent_woomera_context="from-pstn"; my $silent_zapata_group="0"; +my $silent_te_sig_mode='CCS'; + +my $silent_bri_conn_type="point_to_multipoint"; +my $silent_woomera_group="1"; + +my $silent_first_chan=1; +my $silent_last_chan=24; + +my $def_bri_country="europe"; +my $def_bri_operator="etsi"; +my $def_bri_conn_type="Point to multipoint"; my $is_trixbox = $FALSE; my $silent = $FALSE; @@ -88,133 +188,819 @@ my $config_zaptel = $TRUE; my $config_zapata = $TRUE; my $is_smg = $FALSE; +my $tdm_api_span_num=0; +my $zaptel_installed=$FALSE; +my $modprobe_list=`$module_list`; + + +read_args(); +check_zaptel(); +if($boot_only==$TRUE){ + exit( &config_boot()); +} my $current_dir=`pwd`; chomp($current_dir); my $cfg_dir='tmp_cfg'; +my $curdircfg="$current_dir"."/"."$cfg_dir"; + +unless ( -d $curdircfg ) { + $curdircfg = "mkdir " . $curdircfg; + system ($curdircfg); +} + + my $debug_info_file="$current_dir/$cfg_dir/debug_info"; my @hwprobe=`wanrouter hwprobe verbose`; -my $zaptelprobe = `modprobe -l |grep zaptel`; -read_args(); +my $wanpipe_conf_dir="$etc_dir/wanpipe"; +my $asterisk_conf_dir="$etc_dir/asterisk"; + +my $wanrouter_rc_template="$current_dir/templates/wanrouter.rc.template"; + my $zaptel_conf_template="$current_dir/templates/zaptel.conf"; my $zaptel_conf_file="$current_dir/$cfg_dir/zaptel.conf"; -my $zaptel_conf_file_t="/etc/zaptel.conf"; +my $zaptel_conf_file_t="$etc_dir/zaptel.conf"; my $zapata_conf_template="$current_dir/templates/zapata.conf"; my $zapata_conf_file="$current_dir/$cfg_dir/zapata.conf"; -my $zapata_conf_file_t="/etc/asterisk/zapata.conf"; +my $zapata_conf_file_t="$asterisk_conf_dir/zapata.conf"; + +my $bri_conf_template="$current_dir/templates/smg_bri.conf"; +my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; +my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; + +my $woomera_conf_template="$current_dir/templates/woomera.conf"; +my $woomera_conf_file="$current_dir/$cfg_dir/woomera.conf"; +my $woomera_conf_file_t="$asterisk_conf_dir/woomera.conf"; + my $date=`date +%F`; chomp($date); -my $debug_tarball="/etc/wanpipe/debug-".$date.".tgz"; +my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; -if ($is_trixbox==$TRUE){ - $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; - $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; - $zapata_conf_file_t="/etc/asterisk/zapata-auto.conf"; -} +set_zaptel_hwhdlc(); +prepare_files(); +config_t1e1(); +config_bri(); +config_analog(); +summary(); +apply_changes(); +config_boot(); +config_ztcfg_start(); +config_smg_ctrl_start(); +clean_files(); +print "Sangoma cards configuration complete, exiting...\n\n"; -if ($silent==$FALSE){ - if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ - print "Would you like to generate /etc/asterisk/zapata.conf\n"; - if (&prompt_user_list(("YES","NO","")) eq 'NO'){ - $config_zapata = $FALSE; - } + +#######################################FUNCTIONS################################################## + + +sub set_zaptel_hwhdlc{ + if ((system("grep hdlc_hard_xmit '$include_dir/zaptel/zaptel.h'>/dev/null 2>/dev/null")==0)){ + $dchan_str="hardhdlc"; } } -if ($is_smg==$TRUE || $is_tdm_api==$TRUE){ - $config_zapata = $FALSE; +sub config_boot{ + if($no_boot==$TRUE){ + return 1; + } + my $script_name="wanrouter"; + my $current_run_level=3; + my $zaptel_start_level=9; + my $zaptel_stop_level=92; + my $network_start_level=10; + my $wanrouter_start_level=8; + my $wanrouter_stop_level=91; + my $smg_ctrl_start_level=11; + my $command=''; + my $rc_dir=$etc_dir; + + if ($os_type_list =~ m/FreeBSD/){ + return 1; + } + my $res=`cat $etc_dir/inittab |grep id`; + if ($res =~ /id:(\d+):initdefault/){ + $current_run_level=$1; + print "Current boot level is $current_run_level\n"; + } else { + print "Warning: Failed to determine init boot level, assuming 3\n"; + $current_run_level=3; + } + + + print "\nWanrouter boot scripts configuration...\n\n"; + print "Removing existing $script_name boot scripts..."; + $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; + if(system($command) == 0){ + print "OK\n"; + } else { + print "Not installed\n"; + } + if($num_ss7_config!=0){ + $script_name="smgss7_init_ctrl"; + } + + my $res='YES'; + if($silent==$FALSE){ + print ("Would you like $script_name to start on system boot?\n"); + $res= &prompt_user_list("YES","NO",""); + } + + if ( $res eq 'YES'){ + #examine system bootstrap files + $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$rc_dir; + } else { + $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$etc_dir."/rc.d"; + } else { + print "Failed to locate boostrap directory\n"; + print "wanrouter boot scripts will not be installed\n"; + return 1; + } + } + + if($zaptel_installed==$TRUE){ + print "Verifying Zaptel boot scripts..."; + #find zaptel start scripts + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; + $res=`$command`; + if ($res =~ /.*S(\d+)zaptel/){ + $zaptel_start_level=$1; + print "Enabled (level:$zaptel_start_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_start_level"; + } + } else { + print "Not installed\n"; + $zaptel_start_level=0; + } + + #find zaptel stop scripts + print "Verifying Zaptel shutdown scripts..."; + $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find ".$rc_dir."/rc6.d/*zaptel"; + $res=`$command`; + if ($res =~ /.*K(\d+)zaptel/){ + $zaptel_stop_level=$1; + print "Enabled (level:$zaptel_stop_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; + } + } else { + print "Not installed\n"; + $zaptel_stop_level=0; + } + if ($zaptel_start_level != 0){ + $wanrouter_start_level=$zaptel_start_level-1; + } + if ($zaptel_stop_level != 0){ + $wanrouter_stop_level=$zaptel_stop_level-1; + } + } + + my $wanrouter_start_script=''; + if($wanrouter_start_level < 10){ + $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; + } else { + $wanrouter_start_script="S".$wanrouter_start_level.$script_name; + } + my $wanrouter_stop_script=''; + if($wanrouter_stop_level < 10){ + $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; + } else { + $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; + } + + $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; + if(system($command) !=0){ + $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; + if(system($command) !=0){ + print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; + print "$script_name boot scripts not installed\n"; + return 1; } + } + print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; + if(system($command) !=0){ + print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; + print "$script_name start scripts not installed\n"; + return 1; + } + } + + print "Enabling $script_name shutdown scripts ...(level:$wanrouter_stop_level)\n"; + @run_levels= ("0","1","6"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; + if(system($command) !=0){ + print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; + print "$script_name stop scripts not installed\n"; + return 1; + } + } + + if($num_bri_devices != 0){ + #smg_ctrl must start after network + print "Verifying Network boot scripts..."; + $command="find $rc_dir/rc".$current_run_level.".d/*network >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*network"; + $res=`$command`; + if ($res =~ /.*S(\d+)network/){ + $network_start_level=$1; + print "Enabled (level:$network_start_level)\n"; + } else { + print "\nfailed to parse network boot level, assuming $network_start_level"; + } + } else { + print "Not installed\n"; + $network_start_level=0; + } + if ($network_start_level != 0 && $network_start_level > $zaptel_start_level){ + $smg_ctrl_start_level=$network_start_level+1; + print "Enabling smg_ctrl start scripts...(level:$smg_ctrl_start_level)\n"; + $command="install -D -m 755 /usr/sbin/smg_ctrl $rc_dir/init.d/smg_ctrl"; + if(system($command) !=0){ + print "Failed to install smg_ctrl start scripts to $rc_dir/init.d/smg_ctrl"; + print "smg_ctrl start scripts not installed"; + return 1; + } + my $smg_ctrl_start_script=''; + if($smg_ctrl_start_level < 10){ + $smg_ctrl_start_script="S0".$smg_ctrl_start_level."smg_ctrl"; + } else { + $smg_ctrl_start_script="S".$smg_ctrl_start_level."smg_ctrl"; + } + print "Enabling smg_ctrl boot scripts ...(level:$smg_ctrl_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/smg_ctrl ".$rc_dir."/rc".$run_level.".d/".$smg_ctrl_start_script; + if(system($command) !=0){ + print "Failed to install smg_ctrl init script to $rc_dir/rc$run_level.d/$smg_ctrl_start_script\n"; + print "smg_ctrl start scripts not installed\n"; + return 1; + } + } + } + + } + + } + return 0; } -prepare_files(); -config_digital(); -config_analog(); +sub config_ztcfg_start{ + if ($num_zaptel_config ==0 || $silent==$TRUE){ + return; + } + my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) != 0){ + #Zaptel init scripts not installed, prompt for wanpipe_zaptel_start_script + print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + exec_command("cp -f $current_dir/templates/zaptel_cfg_script $wanpipe_conf_dir/scripts/start"); + } + } +} + +sub config_smg_ctrl_start{ + if($num_bri_devices == 0){ + return; + } + my $res; + if($silent==$FALSE) { + print ("Would you like smg_ctrl to start/stop on wanrouter start?\n"); + $res = &prompt_user_list("YES","NO",""); + } else { + $res = "YES"; + } + + if ($res = "YES"){ + #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite + my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; + } else { + $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; + } + + if (system($command) == 0){ + print "smgbri start script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + + $command="cp -f ".$current_dir."/templates/smgbri_stop_script ".$wanpipe_conf_dir."/scripts/stop"; + if (system($command) == 0){ + print "smgbri stop script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + } +} + +sub check_zaptel{ + if ($modprobe_list =~ /zaptel.ko/){ + $zaptel_installed=$TRUE; + } +} + +sub apply_changes{ + my $asterisk_command=''; + my $bri_command=''; + my $asterisk_restart=$FALSE; + my $res=''; + + if($silent==$FALSE) {system('clear')}; + + if($silent==$TRUE){ + $res="Stop now"; + }elsif($is_tdm_api==$TRUE){ + print "\n Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", + "Do not save cfg: Exit", + ""); + }else{ + print "\nZaptel and Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", + "Save cfg: Restart Asterisk & Wanpipe when convenient", + "Save cfg: Stop Asterisk & Wanpipe now", + "Save cfg: Stop Asterisk & Wanpipe when convenient", + "Do not save cfg: Exit", + ""); + } + + + if ($res =~ m/Exit/){ + print "No changes made to your configuration files\n"; + exit 0; + } + if ($res =~ m/now/){ + $asterisk_command='stop now'; + } else { + $asterisk_command='stop when convenient'; + } + + if ($res =~ m/Restart/){ + $asterisk_restart=$TRUE; + } else { + $asterisk_restart=$FALSE; + } + + if ($is_trixbox==$TRUE){ + exec_command("amportal stop"); + unload_zap_modules(); + } elsif ($is_tdm_api==$FALSE ){ + if (`(pidof asterisk)` != 0 ){ + print "\nStopping Asterisk...\n"; + exec_command("asterisk -rx \"$asterisk_command\""); + sleep 2; + while (`(pidof asterisk)` != 0 ){ + if ($asterisk_command eq "stop now"){ + print "Failed to stop asterisk using command: \'$asterisk_command\' \n"; + my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes"); + my $res=&prompt_user_list(@options,""); + + if ( $res =~ m/Force Stop/){ + execute_command("kill -KILL \$(pidof asterisk)"); + } elsif ( $res =~ m/Exit/ ){ + exit(1); + } else { + print "Waiting for asterisk to stop...\n"; + sleep 5; + exec_command("asterisk -rx \"$asterisk_command\""); + } + } else { + #stop when convenient option was selected + print "Waiting for asterisk to stop...\n"; + sleep 3; + } + } -if($devnum==1){ - system('clear'); - print "\n###################################################################"; - print "\n# SUMMARY #"; - print "\n###################################################################\n\n"; - - print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); - exit 0; -}else{ - if (!($is_smg==$TRUE && ($zaptelprobe !~ /zaptel.ko/))){ - if ($num_non_ss7_config != 0 && $config_zaptel==$TRUE){ + + + }else { + print "\nAsterisk is not running...\n"; + } + + } + + if($num_bri_devices != 0){ + exec_command("/usr/sbin/smg_ctrl stop"); + } + + print "\nStopping Wanpipe...\n"; + exec_command("wanrouter stop all"); + + if ($zaptel_installed==$TRUE){ + if($is_tdm_api==$FALSE){ + print "\nUnloading Zaptel modules...\n"; + unload_zap_modules(); + } + } + + print "\nRemoving old configuration files...\n"; + + exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); + + gen_wanrouter_rc(); + + print "\nCopying new Wanpipe configuration files...\n"; + copy_config_files(); + if($num_bri_devices != 0){ + print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; + exec_command("cp -f $bri_conf_file $bri_conf_file_t"); + exec_command("cp -f $woomera_conf_file $woomera_conf_file_t"); + } + + if ($zaptel_installed==$TRUE){ + if($config_zaptel==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; + exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); + } + } + } + + if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; + exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); + } + } + + if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ + print "\nStarting Wanpipe...\n"; + exec_command("wanrouter start"); + + if($num_bri_devices != 0){ + print "Loading SMG BRI...\n"; + sleep 2; + exec_command("/usr/sbin/smg_ctrl start"); + } + + if ($num_zaptel_config != 0){ + print "Loading Zaptel...\n"; + sleep 2; + exec_command("ztcfg -v"); +# } + } + if ($is_trixbox==$TRUE){ + print "\nStarting Amportal...\n"; + exec_command("amportal start"); + sleep 2; + }elsif($config_zapata==$TRUE){ + print "\nStarting Asterisk...\n"; + exec_command("asterisk"); + sleep 2; + + + if ($num_zaptel_config != 0){ + print "\nListing Asterisk channels...\n\n"; + exec_command("asterisk -rx \"zap show channels\""); + } + print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; + }else{ + } + } + print "\nWanrouter start complete...\n"; +} + + + +sub save_debug_info{ + my $version=`wanrouter version`; + chomp($version); + + my $uname=`uname -a`; + chomp($uname); + + my $issue=''; + + if ($os_type_list =~ m/Linux/){ + $issue=`cat $etc_dir/issue`; + chomp($issue); + } + + my $debug_info="\n"; + $debug_info.="===============================================================\n"; + $debug_info.=" SANGOMA DEBUG INFO FILE \n"; + $debug_info.=" Generated on $date \n"; + $debug_info.="===============================================================\n"; + + $debug_info.="\n\nwanrouter hwprobe\n"; + $debug_info.="@hwprobe\n"; + $debug_info.="\nwanrouter version\n"; + $debug_info.="$version\n"; + $debug_info.="\nKernel \"uname -a\"\n"; + $debug_info.="$uname\n"; + if ($os_type_list =~ m/Linux/){ + $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; + $debug_info.="$issue\n"; + } + $debug_info.="EOF\n"; + + open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; + print FH $debug_info; + close (FH); + exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); +} + +sub get_chan_no{ + my ($chan_name,$first_ch, $last_ch)=@_; + + my $res_ch=&prompt_user("\nInput the $chan_name channel for this span [$first_ch-$last_ch]\n"); + while(length($res_ch)==0 ||!($res_ch =~/(\d+)/) + || $res_ch<$first_ch || $res_ch>$last_ch){ + print "Invalid channel, must be between $first_ch and $last_ch\n"; + $res_ch=&prompt_user("Input the channel for this port[$first_ch-$last_ch]"); + } + return $res_ch; +} + +sub get_zapata_context{ + my ($card_model,$card_port)=@_; + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("Select dialplan context for AFT-A%s on port %s\n", $card_model, $card_port); + my $res = &prompt_user_list(@options,$def_zapata_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_zapata_context); + } + + $context=$res_context; + }elsif($res eq $def_zapata_context){ + $context=$def_zapata_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + if($#silent_zapata_contexts >= 0){ + $silent_zapata_context=pop(@silent_zapata_contexts); + } + $context=$silent_zapata_context; + } + $def_zapata_context=$context; + return $context; +} + + +sub get_woomera_context{ + my ($group,$card_model,$card_port,$bri_type)=@_; + + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($bri_type eq 'bri_nt'){ + @options = ("from-internal","Custom"); + } elsif ($bri_type eq 'bri_te'){ + @options = ("from-pstn","Custom"); + } + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("\nSelect dialplan context for group:%d\n", $group); + my $res = &prompt_user_list(@options,$def_woomera_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_woomera_context); + } + + $context=$res_context; + }elsif($res eq $def_woomera_context){ + $context=$def_woomera_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + if($#silent_woomera_contexts >= 0){ + $silent_woomera_context=pop(@silent_woomera_contexts); + } + $context=$silent_woomera_context; + } + $def_woomera_context=$context; + return $context; +} + + + +sub gen_wanrouter_rc{ + #update wanpipe startup sequence + my $rcfile=""; + if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { + open (FH,"$wanrouter_rc_template"); + } + while () { + $rcfile .= $_; + } + close (FH); + open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); + $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; + print FH $rcfile; + close (FH); +} + +sub prepare_files{ + + if ($is_trixbox==$TRUE){ + $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; + $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; + $zapata_conf_file_t="$asterisk_conf_dir/zapata-auto.conf"; + } + + if ($silent==$FALSE){ + if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ + print "Would you like to generate $zapata_conf_file_t\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $config_zapata = $FALSE; + } + } + } + +#remove temp files + my $tmp_cfg_dir="$current_dir"."/"."$cfg_dir"; + if ( -d "$current_dir"."/"."$cfg_dir") { + exec_command("rm -f $current_dir/$cfg_dir/*"); + } +#backup existing configuration files + if ( -f $zaptel_conf_file_t ) { + exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); + } + + if ( -f $zapata_conf_file_t ) { + exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); + } +} + +sub clean_files{ + exec_command("rm -rf $current_dir/$cfg_dir"); +} + + +sub write_zapata_conf{ + my $zp_file=""; + open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; + while () { + $zp_file .= $_; + } + close (FH); + + $zp_file.=$zapata_conf; + + open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; + print FH $zp_file; + close(FH); +} + +sub copy_config_files{ + my @wanpipe_files = split / /, $cfg_string; + exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc $wanpipe_conf_dir"); + foreach my $wanpipe_file (@wanpipe_files) { + exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf $wanpipe_conf_dir"); + } +} + +sub unload_zap_modules{ + my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); + foreach my $module (@modules_list) { + if ($modprobe_list =~ m/$module/){ + exec_command("$module_unload $module"); + } + } +} + +sub write_zaptel_conf{ + my $zp_file=""; + open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + $zp_file=$zp_file.$zaptel_conf; + open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; + print FH $zp_file; + close(FH); +} + +sub summary{ + if($devnum==1){ + if ($silent==$FALSE) {system('clear')}; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); + exit 0; + }else{ + if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ write_zaptel_conf(); } - if ($config_zapata==$TRUE){ + if ($num_bri_devices != 0 ){ + write_bri_conf(); + write_woomera_conf(); + } + if ($num_zaptel_config != 0 && $config_zapata==$TRUE){ write_zapata_conf(); } save_debug_info(); - system('clear'); + if ($silent==$FALSE) {system('clear')}; my $file_list = 1; print "\n###################################################################"; print "\n# SUMMARY #"; print "\n###################################################################\n\n"; print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); + print(" $num_bri_devices_total ISDN BRI port(s) detected, $num_bri_devices configured\n"); print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); - + print "\nConfigurator has created the following files:\n"; - print "\t1. Wanpipe config files in /etc/wanpipe\n"; + print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; $file_list++; - - if ($num_non_ss7_config != 0){ - print "\t$file_list. Zaptel config file /etc/zaptel.conf\n"; + + if ($num_bri_devices != 0){ + print "\t$file_list. sangoma_brid config file $wanpipe_conf_dir/smg_bri\n"; $file_list++; } - if ($config_zapata==$TRUE){ - print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; - } - - if (($num_non_ss7_config != 0) | ($config_zapata==$TRUE)){ - print "\n\nYour original configuration files will be saved to:\n"; - $file_list=1; - } - if ($num_non_ss7_config != 0){ - print "\t$file_list. $zaptel_conf_file_t.bak \n"; + if ($num_zaptel_config != 0){ + print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; $file_list++; } if ($config_zapata==$TRUE){ - print "\t$file_list. $zapata_conf_file_t.bak \n\n"; + print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; } - + + if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ + print "\n\nYour original configuration files will be saved to:\n"; + $file_list=1; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. $zaptel_conf_file_t.bak \n"; + $file_list++; + } + if ($num_zaptel_config !=0 && $config_zapata==$TRUE){ + print "\t$file_list. $zapata_conf_file_t.bak \n\n"; + } + print "\nYour configuration has been saved in $debug_tarball.\n"; print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; if($silent==$FALSE){ prompt_user("Press any key to continue"); } - apply_changes(); - } else { - save_debug_info(); - system('clear'); - print "\n###################################################################"; - print "\n# SUMMARY #"; - print "\n###################################################################\n\n"; - - print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); - print "\nConfigurator has created the following files:\n"; - print "\t1. Wanpipe config files in /etc/wanpipe\n"; - - print "\nYour configuration has been saved in $debug_tarball.\n"; - print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; - prompt_user("Press any key to continue"); - apply_changes(); } } - -#------------------------------FUNCTIONS------------------------------------# sub exec_command{ my @command = @_; if (system(@command) != 0 ){ print "Error executing command:\n@command\n\n"; + if($silent==$FALSE){ + print "Would you like to continue?\n"; + if(&prompt_user_list("No - exit", "YES", "No") eq 'YES'){ + return $?; + } else { + exit $?; + } + } } return $?; } @@ -222,18 +1008,18 @@ sub exec_command{ sub prompt_user{ my($promptString, $defaultValue) = @_; if ($defaultValue) { - print $promptString, "def=\"$defaultValue\": "; + print $promptString, "def=\"$defaultValue\": "; } else { - print $promptString, ": "; + print $promptString, ": "; } $| = 1; # force a flush after our print $_ = ; # get the input from STDIN (presumably the keyboard) chomp; if ("$defaultValue") { - return $_ ? $_ : $defaultValue; # return $_ if it has a value + return $_ ? $_ : $defaultValue; # return $_ if it has a value } else { - return $_; + return $_; } } @@ -244,7 +1030,7 @@ sub prompt_user_list{ my $i; my $valid = 0; for $i (0..$#list-1) { - printf(" %s\. %s\n",$i+1, @list[$i]); + printf(" %s\. %s\n",$i+1, @list[$i]); } while ($valid == 0){ my $list_sz = $#list; @@ -255,19 +1041,19 @@ sub prompt_user_list{ print "]:"; } $| = 1; - $_ = ; + $_ = ; chomp; - if ( $_ eq '' & ! $defaultValue eq ''){ + if ( $_ eq '' & ! $defaultValue eq ''){ print "\n"; - return $defaultValue; + return $defaultValue; } - + if ( $_ =~ /(\d+)/ ){ if ( $1 > $list_sz) { - print "\nError: Invalid option, input a value between 1 and $list_sz \n"; + print "\nError: Invalid option, input a value between 1 and $list_sz \n"; } else { print "\n"; - return @list[$1-1] ; + return @list[$1-1] ; } } else { print "\nError: Invalid option, input an integer\n"; @@ -281,33 +1067,94 @@ sub read_args { $_ = $ARGV[$arg_num]; if( /^--trixbox$/){ $is_trixbox=$TRUE; + }elsif( /^--install_boot_script/){ + $boot_only=$TRUE; }elsif ( /^--tdm_api/){ $is_tdm_api=$TRUE; }elsif ( /^--smg$/){ $is_smg=$TRUE; + }elsif ( /^--no_boot$/){ + $no_boot=$TRUE; + }elsif ( /^--no_hwdtmf$/){ + $no_hwdtmf=$TRUE; }elsif ( /^--silent$/){ $silent=$TRUE; }elsif ( /^--no-zapata$/){ $config_zapata=$FALSE; }elsif ( /^--no-zaptel$/){ $config_zaptel=$FALSE; + }elsif ( $_ =~ /--zapata_context=(\w+)/){ + $silent_zapata_context=substr($_,length("--zapata_context=")); + push(@silent_zapata_contexts, $silent_zapata_context); + }elsif ( $_ =~ /--zapata_group=(\d+)/){ + $silent_zapata_group=$1; + push(@silent_zapata_groups, $silent_zapata_group); + }elsif ( $_ =~ /--woomera_context=(\w+)/){ + $silent_woomera_context=substr($_,length("--woomera_context=")); + push(@silent_woomera_contexts, $silent_woomera_context); + }elsif ( $_ =~ /--woomera_group=(\d+)/){ + $silent_woomera_group=$1; + push(@silent_woomera_groups, $silent_woomera_group); }elsif ( $_ =~ /--fe_media=(\w+)/){ $silent_femedia=$1; if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ printf("Invalid value for fe_media, should be T1/E1\n"); exit(1); + } else { + push(@silent_femedias, $silent_femedia); + if($silent_femedia eq 'E1'){ + if(!($silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ + $silent_feframe='CRC4'; + } + if(!($silent_felcode eq 'HDB3' || $silent_felcode eq 'AMI')){ + $silent_felcode='HDB3'; + } + } + } + }elsif ( $_ =~ /--fractional_chans=(\d+)-(\d+)/ ){ + $silent_first_chan=$1; + $silent_last_chan=$2; + push(@silent_first_chans, $silent_first_chan); + push(@silent_last_chans, $silent_last_chan); + }elsif ( $_ =~ /--hw_dtmf=(\w+)/){ + $silent_hwdtmf=$1; + if(!($silent_hwdtmf eq 'YES' || $silent_hwdtmf eq 'NO')){ + printf("Invalid value for hw_dtmf, should be YES/NO\n"); + exit(1); + } else { + push(@silent_hwdtmfs, $silent_hwdtmf); + } + }elsif ( $_ =~ /--fe_lcode=(\w+)/){ + $silent_felcode=$1; + if(!($silent_felcode eq 'B8ZS' || $silent_felcode eq 'HDB3' || $silent_felcode eq 'AMI')){ + printf("Invalid value for fe_lcode, should be B8ZS/HDB3/AMI \n"); + exit(1); + } else { + push(@silent_felcodes, $silent_felcode); } }elsif ( $_ =~ /--fe_frame=(\w+)/){ $silent_feframe=$1; if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); exit(1); - } + } else { + push(@silent_feframes, $silent_feframe); + } + }elsif ( $_ =~ /--tdm_law=(\w+)/){ + $silent_tdm_law=$1; + if(!($silent_tdm_law eq 'MULAW' || $silent_tdm_law eq 'ALAW')){ + printf("Invalid value for tdm_law, should be MULAW/ALAW\n"); + exit(1); + } else { + push(@silent_tdm_laws, $silent_tdm_law); + } }elsif ( $_ =~ /--fe_clock=(\w+)/){ $silent_feclock=$1; if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); exit(1); + } else { + push(@silent_feclocks, $silent_feclock); } }elsif ( $_ =~ /--signalling=(\w+)/){ my $tmp_signalling=$1; @@ -334,32 +1181,118 @@ sub read_args { }else{ printf("Invalid option for --signalling, options are\n"); printf("\t pri_cpe/pri_net/em/em_w\n"); - printf("\t em/em_w\n"); printf("\t fxo_ls/fxo_gs/fxo_ks\n"); printf("\t fxs_ls/fxs_gs/fxs_ks\n"); exit(1); } + push(@silent_signallings, $silent_signalling); + + }elsif ( $_ =~ /--pri_switchtype=(\w+)/){ + my $tmp_switchtype=$1; + if ($tmp_switchtype eq 'national'){ + $silent_pri_switchtype="national" + }elsif ($tmp_switchtype eq 'dms100'){ + $silent_pri_switchtype="dms100" + }elsif ($tmp_switchtype eq '4ess'){ + $silent_pri_switchtype="4ess" + }elsif ($tmp_switchtype eq '5ess'){ + $silent_pri_switchtype="5ess" + }elsif ($tmp_switchtype eq 'euroisdn'){ + $silent_pri_switchtype="euroisdn" + }elsif ($tmp_switchtype eq 'ni1'){ + $silent_pri_switchtype="ni1" + }elsif ($tmp_switchtype eq 'qsig'){ + $silent_pri_switchtype="qsig" + } else { + printf("Invalid option for --pri_switchtype, options are\n"); + printf("\t national/dms100/4ess/5ess/euroisdn/ni1/qsig"); + exit(1); + } + push(@silent_pri_switchtypes, $silent_pri_switchtype); + }elsif ( $_ =~ /--conf_dir=(.*)/){ + $etc_dir=$1; + if (! -d $etc_dir){ + printf("Error: directory $1 does not exist\n"); + exit(1); + } + }else { + printf("Error: Unrecognized parameter \"$_\" \n"); + exit(1); + } } - + @silent_femedias = reverse(@silent_femedias); + @silent_feframes = reverse(@silent_feframes); + @silent_felcodes = reverse(@silent_felcodes); + @silent_tdm_laws = reverse(@silent_tdm_laws); + @silent_feclocks = reverse(@silent_feclocks); + @silent_signallings = reverse(@silent_signallings); + @silent_pri_switchtypes = reverse(@silent_pri_switchtypes); + @silent_zapata_contexts = reverse(@silent_zapata_contexts); + @silent_woomera_contexts = reverse(@silent_woomera_contexts); + @silent_zapata_groups = reverse(@silent_zapata_groups); + @silent_hwdtmfs = reverse(@silent_hwdtmfs); + @silent_first_chans = reverse(@silent_first_chans); + @silent_last_chans = reverse(@silent_last_chans); + if ($is_trixbox==$TRUE){ print "\nGenerating configuration files for Trixbox\n"; } if ($is_smg==$TRUE){ - print "\nGenerating configuration files for SS7\n"; + print "\nGenerating configuration files for Sangoma Media Gateway\n"; + } + if ($is_tdm_api==$TRUE){ + $config_zapata = $FALSE; } } -sub get_pri_switchtype { - my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); - my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); +#------------------------------BRI FUNCTIONS------------------------------------# +sub get_bri_country { + $def_bri_country = "europe"; + return $def_bri_country; +} + +sub get_woomera_group{ + if($silent==$TRUE){ + if($#silent_woomera_groups >= 0){ + $silent_woomera_group=pop(@silent_woomera_groups); + } + return $silent_woomera_group; + } + + my $group; + my $res_group=&prompt_user("\nInput the group for this port\n",$def_woomera_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ + print "Invalid group, input an integer greater than 0\n"; + $res_group=&prompt_user("Input the group for this port",$def_woomera_group); + } + $group=$res_group; + $def_woomera_group=$group; + return $def_woomera_group; +} + + +sub get_bri_operator { +#warning returning ETSI + $def_bri_operator = "etsi"; + return $def_bri_operator; + + + + my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", + "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", + "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); + + my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); + my $res = &prompt_user_list(@options,$def_switchtype); + my $i; for $i (0..$#options){ if ( $res eq @options[$i] ){ - $def_switchtype=@options[$i]; + $def_bri_operator=@options[$i]; return @options_val[$i]; } } @@ -367,883 +1300,221 @@ sub get_pri_switchtype { exit 1; } -sub unload_zap_modules{ - my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","zaptel"); - foreach my $module (@modules_list) { - exec_command("modprobe -r $module"); - } -} - -sub write_zaptel_conf{ - my $zp_file=""; - open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; - while () { - $zp_file .= $_; +sub write_bri_conf{ + my $bri_file=""; + open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; + while () { + $bri_file .= $_; } close (FH); - $zp_file=$zp_file.$zaptel_conf; - open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; - print FH $zp_file; + $bri_file=$bri_file.$bri_conf; + open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; + print FH $bri_file; close(FH); } -sub write_zapata_conf{ - my $zp_file=""; - open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; - while () { - $zp_file .= $_; +sub write_woomera_conf{ + my $woomera_file=""; + open(FH, "$woomera_conf_template") or die "cannot open $woomera_conf_template"; + while () { + $woomera_file .= $_; } close (FH); - - $zp_file.=$zapata_conf; - - open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; - print FH $zp_file; + $woomera_file=$woomera_file.$woomera_conf; + open(FH, ">$woomera_conf_file") or die "cannot open $woomera_conf_file"; + print FH $woomera_file; close(FH); } -sub copy_config_files{ - my @wanpipe_files = split / /, $startup_string; - exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc /etc/wanpipe"); - foreach my $wanpipe_file (@wanpipe_files) { - exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf /etc/wanpipe"); - } -} -sub apply_changes{ - my $asterisk_command=''; - my $asterisk_restart=$FALSE; - my $res=''; - - system('clear'); +sub get_bri_conn_type{ + my ($port)=@_; if($silent==$TRUE){ - $res="Stop now"; - }elsif($is_tdm_api==$TRUE){ - print "\n Wanpipe configuration complete: choose action\n"; - $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", - "Do not save cfg: Exit", - ""); - }else{ - print "\nZaptel and Wanpipe configuration complete: choose action\n"; - $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", - "Save cfg: Restart Asterisk & Wanpipe when convenient", - "Save cfg: Stop Asterisk & Wanpipe now", - "Save cfg: Stop Asterisk & Wanpipe when convenient", - "Do not save cfg: Exit", - ""); - } - if ($res =~ m/Exit/){ - print "No changes made to your configuration files\n"; - exit 0; - } - if ($res =~ m/now/){ - $asterisk_command='stop now'; - } else { - $asterisk_command='stop when convenient'; - } - - if ($res =~ m/Restart/){ - $asterisk_restart=$TRUE; - } else { - $asterisk_restart=$FALSE; - } - - if ($is_trixbox==$TRUE){ - exec_command("amportal stop"); - unload_zap_modules(); - } elsif ($is_tdm_api==$FALSE){ - print "\nStopping Asterisk...\n"; - exec_command("asterisk -rx \"$asterisk_command\""); - } - - print "\nStopping Wanpipe...\n"; - exec_command("wanrouter stop all"); - - if (!($is_smg==$TRUE && ($zaptelprobe !~ /zaptel.ko/))){ - if($is_tdm_api==$FALSE){ - print "\nUnloading Zaptel modules...\n"; - unload_zap_modules(); + if($#silent_bri_conn_types >= 0){ + $silent_bri_conn_type=pop(@silent_bri_conn_types); } + return $silent_bri_conn_type; } - - print "\nRemoving old configuration files...\n"; - - exec_command("rm -f /etc/wanpipe/wanpipe*.conf"); + printf("\nSelect connection type for port %d\n", $port); + my $conn_type; - gen_wanrouter_rc(); + my @options = ( "Point to multipoint", "Point to point"); + my @options_val = ("point_to_multipoint", "point_to_point"); - print "\nCopying new Wanpipe configuration files...\n"; - copy_config_files(); -# exec_command("cp -f $current_dir/$cfg_dir/* /etc/wanpipe"); - - if (!($is_smg==$TRUE && ($zaptelprobe !~ /zaptel.ko/))){ - if($config_zaptel==$TRUE){ - if ($num_non_ss7_config!=0){ - print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; - exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); - } - } - } + my $res = &prompt_user_list(@options,$def_bri_conn_type); - if ($config_zapata==$TRUE | $is_trixbox==$TRUE){ - print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; - exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); - } - if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ - print "\nStarting Wanpipe...\n"; - exec_command("wanrouter start"); - - if ( ! -e "/etc/wanpipe/scripts/start" & $is_trixbox==$FALSE ){ - print "Loading Zaptel...\n"; - sleep 2; - exec_command("ztcfg -v"); - print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); - if (&prompt_user_list("YES","NO","") eq 'YES'){ - exec_command("cp -f /etc/wanpipe/samples/wanpipe_zaptel_start /etc/wanpipe/scripts/start"); - } + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_conn_type=@options[$i]; + return @options_val[$i]; } - if ($is_trixbox==$TRUE){ - print "\nStarting Amportal...\n"; - exec_command("amportal start"); - sleep 2; - }elsif($config_zapata==$TRUE){ - print "\nStarting Asterisk...\n"; - exec_command("asterisk"); - sleep 2; - - print "\nListing Asterisk channels...\n\n"; - exec_command("asterisk -rx \"zap show channels\""); - print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; - }else{ - print "\nProceed to your Asterisk chan_zap configuration (/etc/asterisk/zapata.conf)\n\n"; - } - } - exit 0; + } + print "Internal error: Invalid BRI connection type\n"; + exit 1; } -sub gen_wanrouter_rc{ - #update wanpipe startup sequence - my $rcfile=""; - open (FH,"$current_dir/templates/rc.template"); - while () { - $rcfile .= $_; + +sub config_bri{ + if($is_smg!=$TRUE && $is_trixbox==$FALSE){ + return; } - close (FH); - open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); - $rcfile =~ s/WPSTARTUP/$startup_string/g; - print FH $rcfile; - close (FH); -} - -sub prepare_files{ - #remove temp files - exec_command("rm -f $current_dir/$cfg_dir/*"); - - #backup existing configuration files - exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); - exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); - -} - -sub save_debug_info{ - my $version=`wanrouter version`; - chomp($version); - - my $uname=`uname -a`; - chomp($uname); - - my $issue=`cat /etc/issue`; - chomp($issue); - - my $debug_info="\n"; - $debug_info.="===============================================================\n"; - $debug_info.=" SANGOMA DEBUG INFO FILE \n"; - $debug_info.=" Generated on $date \n"; - $debug_info.="===============================================================\n"; - - $debug_info.="\n\nwanrouter hwprobe\n"; - $debug_info.="@hwprobe\n"; - $debug_info.="\nwanrouter version\n"; - $debug_info.="$version\n"; - $debug_info.="\nKernel \"uname -a\"\n"; - $debug_info.="$uname\n"; - $debug_info.="\nLinux distribution \"cat /etc/issue\"\n"; - $debug_info.="$issue\n"; - $debug_info.="EOF\n"; - - open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; - print FH $debug_info; - close (FH); - exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); -} - -sub config_analog{ - my $a20x; - system('clear'); + my $a50x; + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + $first_cfg=0; print "------------------------------------\n"; - print "Configuring analog cards [A200/A400]\n"; + print "Configuring ISDN BRI cards [A500]\n"; print "------------------------------------\n"; my $skip_card=$FALSE; $zaptel_conf.="\n"; $zapata_conf.="\n"; foreach my $dev (@hwprobe) { - if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ $skip_card=$FALSE; - my $card = eval {new Card(); } or die ($@); - $card->current_dir($current_dir); - $card->cfg_dir($cfg_dir); - $card->span_no($devnum); - $card->card_model($1); - $card->pci_slot($3); - $card->pci_bus($4); - $card->fe_cpu($5); - my $hwec=$7; - if ($hwec==0){ - $card->hwec_mode('NO'); - } - else{ - $card->hwec_mode('YES'); - } - if ($card->card_model eq '200' | $card->card_model eq '400'){ - $num_analog_devices_total++; - system('clear'); - print "\n-----------------------------------------------------------\n"; - print "A$1 detected on slot:$3 bus:$4\n"; - print "-----------------------------------------------------------\n"; - if($is_trixbox==$FALSE){ - print "\nWould you like to configure A$1 on slot:$3 bus:$4\n"; - if (&prompt_user_list(("YES","NO","")) eq 'NO'){ - $skip_card=$TRUE; - } + if ($1 eq '500'){ + my $card = eval {new Card(); } or die ($@); + + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + + my $hwec=0; + if($6 gt 0){ + $hwec=1; } - if ($skip_card==$FALSE){ - $a20x = eval {new A20x(); } or die ($@); - $a20x->card($card); - $card->first_chan($current_zap_channel); - $current_zap_channel+=24; - $num_non_ss7_config++; - - if ( $device_has_hwec==$TRUE){ - print "Will this A$1 to synchronize with an existing Sangoma T1/E1 card?\n"; - print "\n WARNING: for hardware and firmware requirements, check:\n"; - print " http://wiki.sangoma.com/t1e1analogfaxing\n"; - - if (&prompt_user_list(("YES","NO","")) eq 'NO'){ - $a20x->rm_network_sync('NO'); - } else { - $a20x->rm_network_sync('YES'); - } - } - - print "A$1 configured on slot:$3 bus:$4 span:$devnum\n"; - prompt_user("Press any key to continue"); - $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; - $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; - $startup_string.="wanpipe$devnum "; - - # my $i; - $a20x->gen_wanpipe_conf(); - $devnum++; - $num_analog_devices++; + if ($hwec==0){ + $card->hwec_mode('NO'); }else{ - print "A$1 on slot:$3 bus:$4 not configured\n"; - prompt_user("Press any key to continue"); + $card->hwec_mode('YES'); + } + + if ($card->card_model eq '500'){ + $num_bri_devices_total++; + if($5 eq '1'){ + $bri_device_has_master_clock=$FALSE; + } + if ($silent==$FALSE) { + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + } + +select_bri_option: + if($silent==$FALSE){ + print "\nWould you like to configure AFT-A$1 port $5 on slot:$3 bus:$4\n"; + my @options=("YES", "NO", "Exit"); + $def_bri_option=&prompt_user_list(@options,$def_bri_option); + } else { + $def_bri_option="YES"; + } + + + if($def_bri_option eq 'YES'){ + $skip_card=$FALSE; + $bri_conf.="\n;Sangoma AFT-A$1 port $5 [slot:$3 bus:$4 span:$current_tdmapi_span]"; + }elsif($def_bri_option eq 'NO'){ + $skip_card=$TRUE; + }else{ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } else { + goto select_bri_option; + } + } + if ($skip_card==$FALSE){ + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + $a50x = eval {new A50x(); } or die ($@); + $a50x->card($card); + $a50x->fe_line($5); + $devnum++; + $num_bri_devices++; + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; + }else{ + print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; + prompt_user("Press any key to continue"); + } + + } + } + }elsif (($dev =~ /(\d+):NT/ | + $dev =~ /(\d+):TE/ )& + $skip_card==$FALSE ){ + + + my $context=""; + my $group=""; + my $bri_pos=$a50x->card->tdmv_span_no; + + printf("\nConfiguring port %d on AFT-A%d [slot:%d bus:%d span:%d]\n", $a50x->fe_line(), $a50x->card->card_model(), $a50x->card->pci_slot(), $a50x->card->pci_bus(), $current_tdmapi_span-1); + my $conn_type=get_bri_conn_type($a50x->fe_line()); + my $country=get_bri_country(); + my $operator=get_bri_operator(); + if($is_trixbox==$TRUE && $silent==$FALSE){ + if ( $dev =~ /(\d+):NT/ ){ + $context="from-internal"; + $group=1; + } else { + $context="from-zaptel"; + $group=2; + } + } else { + $group=get_woomera_group(); + #if a context has already been assigned to this group, do not prompt for options + foreach my $f_group (@woomera_groups) { + if($f_group eq $group){ + $context="WOOMERA_NO_CONFIG"; + } + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + if ( $dev =~ /(\d+):NT/ ){ + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_nt'); + } else { + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_te'); + } + push(@woomera_groups, $group); + } } - }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ - my $zap_pos = $1+$current_zap_channel-25; - $a20x->card->zap_context("from-internal"); - $a20x->card->zap_group("1"); - $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); - $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); - }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ - my $zap_pos = $1+$current_zap_channel-25; - $a20x->card->zap_context("from-zaptel"); - $a20x->card->zap_group("0"); - $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); - $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); + $a50x->gen_wanpipe_conf(); + if ( $dev =~ /(\d+):NT/ ){ + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_nt", $group, $country, $operator, $conn_type); + } else { + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + $woomera_conf.=$a50x->gen_woomera_conf($group, $context); + } + } } - - - if($num_analog_devices_total!=0){ - print("\nAnalog card configuration complete\n\n"); + if($num_bri_devices_total!=0){ + print("\nISBN BRI card configuration complete\n\n"); + } else { + print("\nNo Sangoma ISDN BRI cards detected\n\n"); + } + if($silent==$FALSE){ prompt_user("Press any key to continue"); } } -sub config_digital{ - system('clear'); - print "---------------------------------------------\n"; - print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; - print "---------------------------------------------\n"; - - foreach my $dev (@hwprobe) { - if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ - - if ( ! ($1 eq '200' | $1 eq '400') ){ - #do not count analog devices - $num_digital_devices_total++; - } - my $card = eval {new Card(); } or die ($@); - $card->current_dir($current_dir); - $card->cfg_dir($cfg_dir); - $card->span_no($devnum); - $card->card_model($1); - $card->pci_slot($3); - $card->pci_bus($4); - $card->fe_cpu($5); - my $hwec=0; - if ( $dev =~ /HWEC=(\d+)/){ - if($1 gt 0){ - $hwec=1; - } - } - if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ - - my $abc=0; - -} - if ($hwec==0){ - $card->hwec_mode('NO'); - }else{ - $card->hwec_mode('YES'); - } - my $port=$6; - if ($6 eq 'PRI') { - $port=$5; - } - - if ( $card->card_model eq '101' | - $card->card_model eq '102' | - $card->card_model eq '104' | - $card->card_model eq '108' ){ - system('clear'); - if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ - print "A$1 detected on slot:$3 bus:$4\n"; - $device_has_normal_clock=$FALSE; - @device_normal_clocks = ("0"); - } - system('clear'); - my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; - print "\n-----------------------------------------------------------\n"; - print "$msg"; - print "-----------------------------------------------------------\n"; - my $fe_media = ''; - if ($silent==$TRUE){ - $fe_media = $silent_femedia; - } else { - printf ("\nSelect media type for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - my @options = ("T1", "E1", "Unused","Exit"); - $fe_media = prompt_user_list( @options, $def_femedia); - } - - if ( $fe_media eq 'Exit'){ - print "Exit without applying changes?\n"; - if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ - print "No changes made to your configuration files.\n\n"; - exit 0; - } - }elsif ( $fe_media eq 'Unused'){ - $def_femedia=$fe_media; - my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; - print "$msg"; - prompt_user("Press any key to continue"); - }else{ - if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ - $device_has_hwec=$TRUE; - } - - $def_femedia=$fe_media; - $startup_string.="wanpipe$devnum "; - my $a10x; - - if ($1 !~ m/104/ && $2 !~ m/SH/) { - $a10x = eval {new A10u(); } or die ($@); - $a10x->card($card); - if ($5 eq "A") { - $a10x->fe_line("1"); - } else { - $a10x->fe_line("2"); - } - } else { - $a10x = eval {new A10x(); } or die ($@); - if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ - my $abc=0; - } - $a10x->card($card); - $a10x->fe_line($6); - } - - $card->first_chan($current_zap_channel); - $a10x->fe_media($fe_media); - if ( $fe_media eq 'T1' ){ - $current_zap_channel+=24; - $max_chans = 24; - $line_media = 'T1'; - }else{ - $a10x->fe_lcode('HDB3'); - if ($silent==$FALSE){ - printf ("Select framing type for %s on port %s\n", $card->card_model, $port); - my @options = ("CRC4","NCRC4"); - $def_feframe=&prompt_user_list(@options,$def_feframe); - } else { - $def_feframe=$silent_feframe_e1; - } - $a10x->fe_frame($def_feframe); - $current_zap_channel+=31; - $max_chans = 31; - $line_media = 'E1'; - } - if($silent==$FALSE){ - my @options = ("NORMAL", "MASTER"); - printf ("Select clock for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - $def_feclock=&prompt_user_list(@options, $def_feclock); - } else { - $def_feclock=$silent_feclock; - } - $a10x->fe_clock($def_feclock); - - if ( $def_feclock eq 'NORMAL') { - $device_has_normal_clock=$TRUE; - push(@device_normal_clocks, $a10x->fe_line); - } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ - printf("Clock synchronisation options for %s on port %s [slot:%s bus:%s span:$devnum] \n", - $card->card_model, - $port, - $card->pci_slot, - $card->pci_bus); - printf(" Free run: Use internal oscillator on card [default] \n"); - printf(" Port N: Sync with clock from port N \n\n"); - - printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); - $a10x->te_ref_clock($def_te_ref_clock); - } - - my @options=""; - if ($is_smg==$TRUE && ($zaptelprobe =~ /zaptel.ko/)){ - @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); - } elsif ($is_smg==$TRUE && ($zaptelprobe !~ /zaptel.ko/)){ - @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); - } elsif ($is_tdm_api==$TRUE){ - $def_signalling="TDM API"; - } else { - @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); - } - - if ($silent==$FALSE){ - if( $is_tdm_api == $FALSE){ - printf ("Select signalling type for %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - $def_signalling=&prompt_user_list(@options,$def_signalling); - } - } else { - $def_signalling=$silent_signalling; - } - $a10x->signalling($def_signalling); - - my $ss7_chan; - my $ss7_group_start; - my $ss7_group_end; - my @ss7_chan_array; - my @ss7_sorted; - if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ - $a10x->ss7_option(1); - - print("Choose an option below to configure SS7 signalling channels:\n"); - if (&prompt_user_list("Configure consecutive signalling channels(e.g #1-#16)","Configure separate signalling channels(e.g #1,#10)","") eq 'Configure separate signalling channels(e.g #1,#10)'){ - goto SS7CHAN; - while (1){ - print("\nAny other SS7 signalling channel to configure?\n"); - if (&prompt_user_list("YES","NO","") eq 'NO'){ - goto ENDSS7CONFIG; - }else{ -SS7CHAN: $ss7_chan = prompt_user_ss7_chans('Specify the time slot for SS7 signalling(24 for T1? 16 for E1?)'); - push(@ss7_chan_array, $ss7_chan); - $ss7_array_length = @ss7_chan_array; - if ($ss7_array_length == $max_chans){ - goto ENDSS7CONFIG; - } - } - } - }else{ - goto SS7GROUP; - while(1){ - print("\nAny other SS7 consecutive signalling channels to configure?\n"); - if (&prompt_user_list("YES","NO","") eq 'NO'){ - goto ENDSS7CONFIG; - }else{ -SS7GROUP: $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); - $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); - if ($ss7_group_start > $ss7_group_end){ - print("The starting channel number is bigger than the ending one!\n"); - goto SS7GROUP; - } - my $i = 0; - for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ - push(@ss7_chan_array, $i); - my @remove_duplicate; - @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); - $ss7_array_length = @ss7_chan_array; - if ($ss7_array_length > $max_chans){ print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); - @ss7_chan_array = (); - goto SS7GROUP; - } - } - if ($ss7_array_length == $max_chans){ - goto ENDSS7CONFIG; - } - } - } - } - -ENDSS7CONFIG: @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; - print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); - my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); - $ss7_tdmvoicechans = $ss7_voicechans; - #print("Voice channels are: $ss7_voicechans\n "); - #if($ss7_voicechans eq ''){ - # print("No voice channel is configured\n"); - #} - - if ($ss7_voicechans =~ m/(\d+)/){ - $a10x->ss7_tdminterface($1); - } - - $a10x->ss7_tdmchan($ss7_voicechans); - $num_ss7_config++; - }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ - $a10x->ss7_option(2); - $num_ss7_config++; - }elsif ($a10x->signalling eq 'TDM API'){ - $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); - }else{ - $num_non_ss7_config++; - if ($is_smg==$TRUE){ - if ($config_zapata==$TRUE || $asked_autozapata > 0){ - goto Label0; - } - print "Would you like to generate /etc/asterisk/zapata.conf\n"; - if (&prompt_user_list(("YES","NO","")) eq 'YES'){ - $config_zapata = $TRUE; - } - $asked_autozapata++; - } - } - -Label0: if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ - if ($silent==$FALSE && $config_zapata==$TRUE){ - printf ("Select switchtype for %s on port %s \n", $card->card_model, $port); - $a10x->pri_switchtype(get_pri_switchtype()); - } else { - $a10x->pri_switchtype($silent_switchtype); - } - } - - - if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ - $a10x->ss7_subinterface(1); - $a10x->gen_wanpipe_ss7_subinterfaces(); - if ($ss7_tdmvoicechans ne ''){ - $a10x->ss7_subinterface(2); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - my $ss7_element; - foreach $ss7_element (@ss7_sorted){ - $a10x->ss7_sigchan($ss7_element); - $a10x->ss7_subinterface(3); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - $a10x->gen_wanpipe_conf(); - if ($ss7_tdmvoicechans ne ''){ - $a10x->ss7_subinterface(5); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - foreach $ss7_element (@ss7_sorted){ - $a10x->ss7_sigchan($ss7_element); - $a10x->ss7_subinterface(6); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - }else{ - $a10x->gen_wanpipe_conf(); - } - if ($is_smg==$TRUE && $config_zapata==$FALSE){ - if ($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)'){ - goto Label1; - } - $zaptel_conf.=$a10x->gen_zaptel_conf(); - }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ - if ($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)'){ - goto Label1; - }else{ - $zaptel_conf.=$a10x->gen_zaptel_conf(); - $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); - $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); - $zapata_conf.=$a10x->gen_zapata_conf(); - } - }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ - $zaptel_conf.=$a10x->gen_zaptel_conf(); - $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); - $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); - $zapata_conf.=$a10x->gen_zapata_conf(); - }elsif ($is_tdm_api == $FALSE){ - $zaptel_conf.=$a10x->gen_zaptel_conf(); - } - -Label1: $devnum++; - $num_digital_devices++; - my $msg ="\n\nPort ".$port." on A".$card->card_model." configuration complete...\n"; - print "$msg"; - if($silent==$FALSE){ - prompt_user("Press any key to continue"); - } - - } - } - - ##################################### - # for A101/2u, A101/2c # - ##################################### - - }elsif ( $dev =~ /A(\d+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+)/){ - - die "SHOULD NOT BE HERE"; - - system('clear'); - $num_digital_devices_total++; - my $card = eval {new Card(); } or die ($@); - $card->current_dir($current_dir); - $card->cfg_dir($cfg_dir); - $card->span_no($devnum); - $card->card_model($1); - $card->pci_slot($2); - $card->pci_bus($3); - $card->fe_cpu($4); - my $port; - if( $4 eq 'A' ){ - print "\n\nSangoma single/dual T1/E1 card detected on slot:$2 bus:$3\n"; - print "Select configuration options:\n"; - - $port=1; - }else{ - $port=2; - } - printf ("\nSelect media type for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - my @options = ("T1", "E1", "Unused", "Exit"); - my $fe_media = &prompt_user_list(@options,""); - if ( $fe_media eq 'Exit'){ - print "Exit without applying changes?\n"; - if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ - print "No changes made to your configuration files\n"; - exit 0; - } - }elsif ( $fe_media eq 'Unused'){ - print "A$1 on slot:$2 bus:$3 port:$4 not configured\n"; - }else{ - $num_digital_devices++; - $startup_string.="wanpipe$devnum "; - my $a10u = eval {new A10u(); } or die ($@); - $a10u->card($card); - $card->first_chan($current_zap_channel); - $a10u->fe_line($port); - $a10u->fe_media($fe_media); - if ( $fe_media eq 'T1' ){ - $current_zap_channel+=24; - $max_chans = 24; - $line_media = 'T1'; - }else{ - $a10u->fe_lcode('HDB3'); - printf ("Select framing type for %s on port %s\n", $card->card_model, $6); - my @options = ("CRC4","NCRC4"); - $a10u->fe_frame(&prompt_user_list(@options,"")); - $current_zap_channel+=31; - $max_chans = 31; - $line_media = 'E1'; - } - my @options = ("NORMAL", "MASTER"); - printf ("Select clock type for %s on port %s\n", $card->card_model, $a10u->fe_line); - $a10u->fe_clock(&prompt_user_list(@options,"")); - - if ($is_smg==$TRUE && ($zaptelprobe =~ /zaptel.ko/)){ - @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); - } elsif ($is_smg==$TRUE && ($zaptelprobe !~ /zaptel.ko/)){ - @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); - } else { - @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); - } - - printf ("Select signalling type for %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $a10u->fe_line, $card->pci_slot, $card->pci_bus); - - $a10u->signalling(&prompt_user_list(@options,"")); - - my $ss7_chan_a10u; - my $ss7_group_start_a10u; - my $ss7_group_end_a10u; - my @ss7_chan_array_a10u; - my @ss7_sorted_a10u; - if( $a10u->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ - $a10u->ss7_option(1); - - print("Choose an option below to configure SS7 signalling channels:\n"); - if (&prompt_user_list("Configure consecutive signalling channels(e.g #1-#16)","Configure separate signalling channels(e.g #1,#10)","") eq 'Configure separate signalling channels(e.g #1,#10)'){ - goto SS7CHAN_A10U; - while (1){ - print("\nAny other SS7 signalling channel to configure?\n"); - if (&prompt_user_list("YES","NO","") eq 'NO'){ - goto ENDSS7CONFIG_A10U; - }else{ -SS7CHAN_A10U: $ss7_chan_a10u = prompt_user_ss7_chans('Specify the time slot for SS7 signalling(24 for T1? 16 for E1?)'); - push(@ss7_chan_array_a10u, $ss7_chan_a10u); - $ss7_array_length = @ss7_chan_array_a10u; - if ($ss7_array_length == $max_chans){ - goto ENDSS7CONFIG_A10U; - } - } - } - }else{ - goto SS7GROUP_A10U; - while(1){ - print("\nAny other SS7 consecutive signalling channels to configure?\n"); - if (&prompt_user_list("YES","NO","") eq 'NO'){ - goto ENDSS7CONFIG_A10U; - }else{ -SS7GROUP_A10U: $ss7_group_start_a10u = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); - $ss7_group_end_a10u = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); - if ($ss7_group_start_a10u > $ss7_group_end_a10u){ - print("The starting channel number is bigger than the ending one!\n"); - goto SS7GROUP_A10U; - } - my $i = 0; - for ($i = $ss7_group_start_a10u; $i <= $ss7_group_end_a10u; $i++){ - push(@ss7_chan_array_a10u, $i); - my @remove_duplicate_a10u; - @ss7_chan_array_a10u = grep(!$remove_duplicate_a10u[$_]++, @ss7_chan_array_a10u); - $ss7_array_length = @ss7_chan_array_a10u; - if ($ss7_array_length > $max_chans){ print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); - @ss7_chan_array_a10u = (); - goto SS7GROUP_A10U; - } - } - if ($ss7_array_length == $max_chans){ - goto ENDSS7CONFIG_A10U; - } - } - } - } - -ENDSS7CONFIG_A10U: @ss7_sorted_a10u = sort { $a <=> $b } @ss7_chan_array_a10u; - print("\nYou configure the following SS7 signalling channels: @ss7_sorted_a10u\n"); - my $ss7_voicechans_a10u = gen_ss7_voicechans(@ss7_sorted_a10u,$max_chans); - - $ss7_tdmvoicechans = $ss7_voicechans_a10u; - - #print("Voice channels are: $ss7_voicechans_a10u\n "); - #if($ss7_voicechans_a10u eq ''){ - # print("No voice channel is configured\n"); - #} - if ($ss7_voicechans_a10u =~ m/(\d+)/){ - $a10u->ss7_tdminterface($1); - } - - $a10u->ss7_tdmchan($ss7_voicechans_a10u); - $num_ss7_config++; - }elsif ( $a10u->signalling eq 'No Signaling (Voice Only)'){ - $a10u->ss7_option(2); - $num_ss7_config++; - }else{ - $num_non_ss7_config++; - if ($is_smg==$TRUE){ - if ($config_zapata==$TRUE || $asked_autozapata > 0){ - goto Label0_A10U; - } - print "Would you like to generate /etc/asterisk/zapata.conf\n"; - if (&prompt_user_list(("YES","NO","")) eq 'YES'){ - $config_zapata = $TRUE; - } - $asked_autozapata++; - } - } - -Label0_A10U: if ( $a10u->signalling eq 'PRI CPE' | $a10u->signalling eq 'PRI NET' ){ - if ($config_zapata==$TRUE){ - printf ("Select switchtype for %s on port %s \n", $card->card_model, $port); - $a10u->pri_switchtype(get_pri_switchtype()); - } - } - - if( $a10u->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ - $a10u->ss7_subinterface(1); - $a10u->gen_wanpipe_ss7_subinterfaces(); - if ($ss7_tdmvoicechans ne ''){ - $a10u->ss7_subinterface(2); - $a10u->gen_wanpipe_ss7_subinterfaces(); - } - my $ss7_element_a10u; - foreach $ss7_element_a10u (@ss7_sorted_a10u){ - $a10u->ss7_sigchan($ss7_element_a10u); - $a10u->ss7_subinterface(3); - $a10u->gen_wanpipe_ss7_subinterfaces(); - } - $a10u->gen_wanpipe_conf(); - if ($ss7_tdmvoicechans ne ''){ - $a10u->ss7_subinterface(5); - $a10u->gen_wanpipe_ss7_subinterfaces(); - } - foreach $ss7_element_a10u (@ss7_sorted_a10u){ - $a10u->ss7_sigchan($ss7_element_a10u); - $a10u->ss7_subinterface(6); - $a10u->gen_wanpipe_ss7_subinterfaces(); - } - }else{ - $a10u->gen_wanpipe_conf(); - } - if ($is_smg==$TRUE && $config_zapata==$FALSE){ - if ($a10u->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10u->signalling eq 'No Signaling (Voice Only)'){ - goto Label1_A10U; - } - $zaptel_conf.=$a10u->gen_zaptel_conf(); - }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ - if ($a10u->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10u->signalling eq 'No Signaling (Voice Only)'){ - goto Label1_A10U; - }else{ - $zaptel_conf.=$a10u->gen_zaptel_conf(); - $a10u->card->zap_context(&get_zapata_context($a10u->card->card_model,$port)); - $a10u->card->zap_group(&get_zapata_group($a10u->card->card_model,$port,$a10u->card->zap_context)); - $zapata_conf.=$a10u->gen_zapata_conf(); - } - }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ - $zaptel_conf.=$a10u->gen_zaptel_conf(); - $a10u->card->zap_context(&get_zapata_context($a10u->card->card_model,$port)); - $a10u->card->zap_group(&get_zapata_group($a10u->card->card_model,$port,$a10u->card->zap_context)); - $zapata_conf.=$a10u->gen_zapata_conf(); - }else{ - $zaptel_conf.=$a10u->gen_zaptel_conf(); - } - - -Label1_A10U: $devnum++; - $num_digital_devices++; - print "Port $port configuration complete\n"; - prompt_user("Press any key to continue"); - } - } - } - if($num_digital_devices_total!=0){ - print("\nT1/E1 card configuration complete.\n"); - if($silent==$FALSE){ - prompt_user("Press any key to continue"); - } - } - close SCR; -} - +#------------------------------T1/E1 FUNCTIONS------------------------------------# sub get_te_ref_clock{ my @list_normal_clocks=@_; @@ -1271,146 +1542,6 @@ sub get_te_ref_clock{ exit 1; } -sub get_zapata_context{ - my ($card_model,$card_port)=@_; - my $context=''; - my @options = ("from-pstn", "from-internal","Custom"); - - if($is_trixbox==$TRUE){ - @options = ("PSTN", "INTERNAL"); - } - if ($silent==$FALSE){ - printf ("Select dialplan context for A%s on port %s\n", $card_model, $card_port); - my $res = &prompt_user_list(@options,$def_zapata_context); - if($res eq "PSTN"){ - $context="from-zaptel"; - }elsif($res eq "INTERNAL"| $res eq "from-internal"){ - $context="from-internal"; - }elsif($res eq "from-pstn"){ - $context="from-pstn"; - }elsif($res eq "Custom"){ - my $res_context=&prompt_user("Input the context for this port"); - while(length($res_context)==0){ - print "Invalid context, input a non-empty string\n"; - $res_context=&prompt_user("Input the context for this port",$def_zapata_context); - } - - $context=$res_context; - }elsif($res eq $def_zapata_context){ - $context=$def_zapata_context; - }else{ - print "Internal error:invalid context,group\n"; - exit 1; - } - }else{ - $context=$silent_zapata_context; - } - $def_zapata_context=$context; - return $context; -} -sub get_zapata_group{ - my ($card_model,$card_port,$context)=@_; - my $group=''; - if($is_trixbox==$TRUE){ - if($context eq "from-zaptel"){ - $group=0; - return $group; - }elsif($context eq "from-internal"){ - $group=1; - return $group; - }else{ - print "Internal error:invalid group for Trixbox\n"; - } - }else{ - if($context eq "from-pstn"){ - $group=0; - }elsif($context eq "from-internal"){ - $group=1; - }else{ - my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); - while(length($res_group)==0 |!($res_group =~/(\d+)/)){ - print "Invalid group, input an integer.\n"; - $res_group=&prompt_user("Input the group for this port",$def_zapata_group); - } - $group=$res_group; - $def_zapata_group=$group; - } - } - - return $group; -} - -sub gen_ss7_voicechans{ - my @ss7_array = @_; - my $T1CHANS = pop(@ss7_array); - my $count = @ss7_array; - my $output =''; - my $chan_in = 1; - my $chan_de = 0; - my $flag = 0; - my $i = 0; - my $j = 0; - - while($i < $count){ - $j = $i + 1; - if ($ss7_array[$i] > 2 && $i == 0){ - $chan_de = $ss7_array[$i] - 1; - $output .= "1-$chan_de"; - $flag = 1; - }elsif ($ss7_array[$i] == 2 && $i == 0){ - $output .= "1"; - $flag = 1; - } - - if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ - goto Incrementing; - }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ - goto Incrementing; - } - - if ($i < ($count-1)){ - $chan_in = $ss7_array[$i]+1; - if ($chan_in < ($ss7_array[$j]-1)){ - $chan_de = $ss7_array[$j] - 1; - if ($flag != 0){ - $output .= ".$chan_in-$chan_de"; - }else{ - $output .= "$chan_in-$chan_de"; - $flag = 1; - } - } - else{ - if ($flag != 0){ - $output .= ".$chan_in"; - }else{ - $output .= "$chan_in"; - $flag = 1; - } - } - }else{ - $chan_in = $ss7_array[$i]+1; - if ($chan_in < $T1CHANS){ - $chan_de = $T1CHANS; - if ($flag != 0){ - $output .= ".$chan_in-$chan_de"; - }else{ - $output .= "$chan_in-$chan_de"; - $flag = 1; - } - }else{ - if ($flag != 0){ - $output .= ".$T1CHANS"; - }else{ - $output .= "$T1CHANS"; - $flag = 1; - } - } - } - -Incrementing: $i++; - } - return $output; -} sub prompt_user_hw_dchan{ @@ -1421,7 +1552,7 @@ sub prompt_user_hw_dchan{ printf("Hardware HDLC can be performed on the data channel.\n"); prompt_hw_dchan: my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); - while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ + while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ print "Invalid channel, input an integer (0 for unused).\n"; $res_dchan=&prompt_user("Select the data channel","0"); } @@ -1448,6 +1579,164 @@ prompt_hw_dchan: } +sub get_zapata_group{ + my ($card_model,$card_port,$context)=@_; + my $group=''; + if($silent==$TRUE){ + if($#silent_zapata_groups >= 0){ + $silent_zapata_group=pop(@silent_zapata_groups); + } + $silent_zapata_group = + return $silent_zapata_group; + } + if($is_trixbox==$TRUE){ + if($context eq "from-zaptel"){ + $group=0; + return $group; + }elsif($context eq "from-internal"){ + $group=1; + return $group; + }else{ + print "Internal error:invalid group for Trixbox\n"; + } + }else{ + if($context eq "from-pstn"){ + $group=0; + }elsif($context eq "from-internal"){ + $group=1; + }else{ + my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)){ + print "Invalid group, input an integer.\n"; + $res_group=&prompt_user("Input the group for this port",$def_zapata_group); + } + $group=$res_group; + $def_zapata_group=$group; + } + } + + return $group; +} + + + +sub prompt_hw_dtmf { +#HW DTMF not supported in the 3.2 drivers +# return "NO"; + if( $no_hwdtmf == $TRUE){ + return "NO"; + } + print("Would you like to enable hardware DTMF detection?\n"); + my @options = ("YES","NO"); + $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); + return $def_hw_dtmf; +} + +sub prompt_tdm_law { + print("Which codec will be used?\n"); + my @options = ("MULAW - North America","ALAW - Europe"); + my @options_val = ("MULAW", "ALAW"); + my $res = &prompt_user_list(@options, $def_tdm_law); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_tdm_law=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid TDM LAW type\n"; + exit 1; +} + + +sub get_pri_switchtype { + my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); + my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); + my $res = &prompt_user_list(@options,$def_switchtype); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_switchtype=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + + +sub gen_ss7_voicechans{ + my @ss7_array = @_; + my $T1CHANS = pop(@ss7_array); + my $count = @ss7_array; + my $output =''; + my $chan_in = 1; + my $chan_de = 0; + my $flag = 0; + my $i = 0; + my $j = 0; + + while($i < $count){ + $j = $i + 1; + if ($ss7_array[$i] > 2 && $i == 0){ + $chan_de = $ss7_array[$i] - 1; + $output .= "1-$chan_de"; + $flag = 1; + }elsif ($ss7_array[$i] == 2 && $i == 0){ + $output .= "1"; + $flag = 1; + } + + if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ + goto Incrementing; + }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ + goto Incrementing; + } + + if ($i < ($count-1)){ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < ($ss7_array[$j]-1)){ + $chan_de = $ss7_array[$j] - 1; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$chan_in"; + }else{ + $output .= "$chan_in"; + $flag = 1; + } + } + }else{ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < $T1CHANS){ + $chan_de = $T1CHANS; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$T1CHANS"; + }else{ + $output .= "$T1CHANS"; + $flag = 1; + } + } + } + +Incrementing: + $i++; + } + return $output; +} + sub prompt_user_ss7_chans{ my @ss7_string = @_; my $def_ss7_group_chan = ''; @@ -1455,21 +1744,741 @@ sub prompt_user_ss7_chans{ my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ - print("ERROR: Invalid channel number, input an integer only.\n\n"); - $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); - } + print("ERROR: Invalid channel number, input an integer only.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); +} if ($line_media eq 'T1'){ - while ($ss7_group_chan>24 || $ss7_group_chan<1){ - print("Invalid channel number, there are only 24 channels in T1.\n\n"); - $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); - goto CHECK1; - } - }elsif ($line_media eq 'E1'){ - while ($ss7_group_chan>31 || $ss7_group_chan<1){ - print("Invalid channel number, there are only 31 channels in E1.\n\n"); + while ($ss7_group_chan>24 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 24 channels in T1.\n\n"); $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); goto CHECK1; - } - } +} +}elsif ($line_media eq 'E1'){ + while ($ss7_group_chan>31 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 31 channels in E1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +} return $ss7_group_chan; } + + + + + + +sub config_t1e1{ + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + print "---------------------------------------------\n"; + print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; + print "---------------------------------------------\n"; + + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + + if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ + #do not count analog devices + $num_digital_devices_total++; + } + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + + my $hwec=0; + if ( $dev =~ /HWEC=(\d+)/){ + if($1 gt 0){ + $hwec=1; + } + } + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + my $port=$6; + if ($6 eq 'PRI') { + $port=$5; + } + + if ( $card->card_model eq '101' | + $card->card_model eq '102' | + $card->card_model eq '104' | + $card->card_model eq '108' ){ + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ + print "A$1 detected on slot:$3 bus:$4\n"; + $device_has_normal_clock=$FALSE; + @device_normal_clocks = ("0"); + } + $first_cfg=0; + if($silent==$FALSE){ + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; + print "$msg"; + print "-----------------------------------------------------------\n"; + } + my $fe_media = ''; + if ($silent==$TRUE){ + if($#silent_femedias >= 0){ + $silent_femedia=pop(@silent_femedias); + } + + $fe_media = $silent_femedia; + } else { + printf ("\nSelect media type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + my @options = ("T1", "E1", "Unused","Exit"); + $fe_media = prompt_user_list( @options, $def_femedia); + } + + if ( $fe_media eq 'Exit'){ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } + }elsif ( $fe_media eq 'Unused'){ + $def_femedia=$fe_media; + my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; + print "$msg"; + prompt_user("Press any key to continue"); + }else{ + if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ + $device_has_hwec=$TRUE; + } + + $def_femedia=$fe_media; + $cfg_string.="wanpipe$devnum "; + my $a10x; + + if ($1 !~ m/104/ && $2 !~ m/SH/) { + $a10x = eval {new A10u(); } or die ($@); + $a10x->card($card); + if ($5 eq "A") { + $a10x->fe_line("1"); + } else { + $a10x->fe_line("2"); + } + } else { + $a10x = eval {new A10x(); } or die ($@); + if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + $a10x->card($card); + $a10x->fe_line($6); + } + + $card->first_chan($current_zap_channel); + $a10x->fe_media($fe_media); + if ( $fe_media eq 'T1' ){ + $max_chans = 24; + $line_media = 'T1'; + + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + + + if ($silent==$FALSE){ + printf ("Configuring port %s on AFT-A%s as: %s, coding:%s, framing:%s.\n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe, + $port); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("B8ZS", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("ESF", "D4"); + $def_feframe= &prompt_user_list(@options, $def_feframe); + } + + + } else { + if($#silent_felcodes >= 0){ + $silent_felcode=pop(@silent_felcodes); + } + $def_felcode=$silent_felcode; + + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + + if($#silent_feframes >= 0){ + $silent_feframe=pop(@silent_feframes); + } + $def_feframe=$silent_feframe; + + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + } + + + }else{ #fe_media = E1 + $max_chans = 31; + $line_media = 'E1'; + + + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("HDB3", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("CRC4", "NCRC4","UNFRAMED"); + $def_feframe = &prompt_user_list(@options, $def_feframe); + +# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); +# my @options = ("CCS - Clear channel signalling ", "CAS"); +# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); + + } + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode on AFT-A%s port %s\n",$card->card_model, $port); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + } else { + $def_te_sig_mode="CAS"; + } + + + } else { + if($#silent_felcodes >= 0){ + $silent_felcode=pop(@silent_felcodes); + } + $def_felcode=$silent_felcode; + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + + if($#silent_feframes >= 0){ + $silent_feframe=pop(@silent_feframes); + } + $def_feframe=$silent_feframe; + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + } + + + } + $a10x->fe_lcode($def_felcode); + $a10x->fe_frame($def_feframe); + if($silent==$FALSE){ + my @options = ("NORMAL", "MASTER"); + printf ("Select clock for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_feclock=&prompt_user_list(@options, $def_feclock); + } else { + if($#silent_feclocks >= 0){ + $silent_feclock=pop(@silent_feclocks); + } + $def_feclock=$silent_feclock; + } + + $a10x->fe_clock($def_feclock); + if ( $def_feclock eq 'NORMAL') { + $device_has_normal_clock=$TRUE; + push(@device_normal_clocks, $a10x->fe_line); + } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ + printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", + $card->card_model, + $port, + $card->pci_slot, + $card->pci_bus); + printf(" Free run: Use internal oscillator on card [default] \n"); + printf(" Port N: Sync with clock from port N \n\n"); + + printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); + $a10x->te_ref_clock($def_te_ref_clock); + } + + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if($#silent_hwdtmfs >= 0){ + $silent_hwdtmf=pop(@silent_hwdtmfs); + } + if ($card->hwec_mode eq "YES" && $no_hwdtmf==$FALSE){ + $card->hw_dtmf($silent_hwdtmf); + } else { + $card->hw_dtmf("NO"); + } + } + + + + my @options=""; + if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_smg==$TRUE && $zaptel_installed==$FALSE){ + @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_tdm_api==$TRUE){ + $def_signalling="TDM API"; + } else { + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); + } + if ($silent==$FALSE){ + if( $is_tdm_api == $FALSE){ + printf ("Select signalling type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_signalling=&prompt_user_list(@options,$def_signalling); + } + } else { + if($#silent_signallings >= 0){ + $silent_signalling=pop(@silent_signallings); + } + $def_signalling=$silent_signalling; + } + $a10x->signalling($def_signalling); + + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + + } else { + $def_te_sig_mode="CAS"; + } + $a10x->te_sig_mode($def_te_sig_mode); + + my $ss7_chan; + my $ss7_group_start; + my $ss7_group_end; + my @ss7_chan_array; + my @ss7_sorted; + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_option(1); + print("Choose an option below to configure SS7 signalling channels:\n"); + my @options =("Configure individual signalling channels(e.g #1,#10)", + "Configure consecutive signalling channels(e.g #1-#16)"); + my $res = &prompt_user_list(@options, ""); + if ( $res eq 'Configure individual signalling channels(e.g #1,#10)'){ + goto SS7CHAN; + while (1){ + print("\nAny other SS7 signalling channel to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7CHAN: + $ss7_chan = prompt_user_ss7_chans('Specify the channel for SS7 signalling(24 for T1? 16 for E1?)'); + push(@ss7_chan_array, $ss7_chan); + $ss7_array_length = @ss7_chan_array; + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + }else{ + goto SS7GROUP; + while(1){ + print("\nAny other SS7 consecutive signalling channels to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7GROUP: + $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); + $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); + if ($ss7_group_start > $ss7_group_end){ + print("The starting channel number is bigger than the ending one!\n"); + goto SS7GROUP; + } + my $i = 0; + for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ + push(@ss7_chan_array, $i); + my @remove_duplicate; + @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); + $ss7_array_length = @ss7_chan_array; + + if ($ss7_array_length > $max_chans){ + print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); + + @ss7_chan_array = (); + goto SS7GROUP; + } + } + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + } + +ENDSS7CONFIG: + + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); + my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); + $ss7_tdmvoicechans = $ss7_voicechans; + + if ($ss7_voicechans =~ m/(\d+)/){ + $a10x->ss7_tdminterface($1); + } + + $a10x->ss7_tdmchan($ss7_voicechans); + + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + + #wanrouter start/stop for signalling span is controlled by ss7boxd + #$startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ + $a10x->ss7_option(2); + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + + }elsif ($a10x->signalling eq 'TDM API'){ + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); + } + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + }else{ + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $startup_string.="wanpipe$devnum "; + $current_zap_span++; + $current_zap_channel+=$max_chans; + } + + + + if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ + if ($silent==$FALSE && $config_zapata==$TRUE){ + printf ("Select switchtype for AFT-A%s on port %s \n", $card->card_model, $port); + $a10x->pri_switchtype(get_pri_switchtype()); + } else { + if($#silent_pri_switchtypes >= 0){ + $silent_pri_switchtype=pop(@silent_pri_switchtypes); + } + $def_feframe=$silent_feframe; + $a10x->pri_switchtype($silent_pri_switchtype); + } + } + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_subinterface(1); + $a10x->gen_wanpipe_ss7_subinterfaces(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(2); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + my $ss7_element; + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + + $a10x->gen_wanpipe_conf(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + }else{ + $a10x->gen_wanpipe_conf(); + } + + if ($is_smg==$TRUE && $config_zapata==$FALSE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' + | $a10x->signalling eq 'No Signaling (Voice Only)')){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ + + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + } + }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + if($silent==$FALSE){ + printf ("Configuring port %s on %s as a full %s\n", $a10x->fe_line(), $a10x->card->card_model(),$a10x->fe_media()); + my $res=&prompt_user_list("YES - Use all channels", "NO - Configure for fractional","YES"); + if ($res =~ m/NO/){ + my $max_chan=0; + if($a10x->fe_media eq 'T1'){ + $max_chan=24; + } else { + $max_chan=31; + } + my $first_chan = &get_chan_no("first",1,$max_chan-1); + my $last_chan = &get_chan_no("last",$first_chan+1,$max_chan); + + $a10x->frac_chan_first($first_chan); + $a10x->frac_chan_last($last_chan); + } + } else { + if($#silent_first_chans >= 0){ + $silent_first_chan = pop(@silent_first_chans); + $silent_last_chan = pop(@silent_last_chans); + } + + if($silent_first_chan != 0){ + $a10x->frac_chan_first($silent_first_chan); + $a10x->frac_chan_last($silent_last_chan); + } + } + + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + }elsif ($is_tdm_api == $FALSE){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + $devnum++; + $num_digital_devices++; + my $msg ="\nPort ".$port." on AFT-A".$card->card_model." configuration complete...\n"; + print "$msg"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + } + + + } + + } + } + if($num_digital_devices_total!=0){ + print("\nT1/E1 card configuration complete.\n"); + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + $first_cfg=0; + } +# close SCR; +} + + +#------------------------------ANALOG FUNCTIONS------------------------------------# + + +sub config_analog{ + if($is_tdm_api==$TRUE){ + return; + } + my $a20x; + if (!$first_cfg && $silent==$FALSE) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring analog cards [A200/A400]\n"; + print "------------------------------------\n"; + + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ + $skip_card=$FALSE; + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + my $hwec=$7; + if ($hwec==0){ + $card->hwec_mode('NO'); + } + else{ + $card->hwec_mode('YES'); + } + if ($card->card_model eq '200' | $card->card_model eq '400'){ + $num_analog_devices_total++; + if($silent==$FALSE) { + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + } + if($is_trixbox==$FALSE){ + if ($silent==$FALSE){ + print "\nWould you like to configure AFT-A$1 on slot:$3 bus:$4\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $skip_card=$TRUE; + } + } + } + if ($skip_card==$FALSE){ + + $a20x = eval {new A20x(); } or die ($@); + $a20x->card($card); + $card->first_chan($current_zap_channel); + + if ( $device_has_hwec==$TRUE && $silent==$FALSE){ + print "Will this AFT-A$1 synchronize with an existing Sangoma T1/E1 card?\n"; + print "\n WARNING: for hardware and firmware requirements, check:\n"; + print " http://wiki.sangoma.com/t1e1analogfaxing\n"; + + if (&prompt_user_list(("NO","YES","")) eq 'NO'){ + $a20x->rm_network_sync('NO'); + } else { + $a20x->rm_network_sync('YES'); + } + } + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + $a20x->tdm_law(&prompt_tdm_law()); + } else { + if($#silent_hwdtmfs >= 0){ + $silent_hwdtmf=pop(@silent_hwdtmfs); + } + + if ($card->hwec_mode eq "YES" && $no_hwdtmf==$FALSE){ + $card->hw_dtmf($silent_hwdtmf); + } else { + $card->hw_dtmf("NO"); + } + + if($#silent_tdm_laws >= 0){ + $silent_tdm_law=pop(@silent_tdm_laws); + } + + $a20x->tdm_law($silent_tdm_law); + } + + + print "A$1 configured on slot:$3 bus:$4 span:$current_zap_span\n"; + $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + $current_zap_channel+=24; + my $i; + $devnum++; + $num_analog_devices++; + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + $a20x->gen_wanpipe_conf(); + + }else{ + print "A$1 on slot:$3 bus:$4 not configured\n"; + prompt_user("Press any key to continue"); + } + } + }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + if($silent==$TRUE){ + if($#silent_zapata_contexts >= 0){ + $silent_zapata_context=pop(@silent_zapata_contexts); + } + $a20x->card->zap_context($silent_zapata_context); + } else { + $a20x->card->zap_context("from-internal"); + } + $a20x->card->zap_group("1"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); + }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + if($silent==$TRUE){ + if($#silent_zapata_contexts >= 0){ + $silent_zapata_context=pop(@silent_zapata_contexts); + } + $a20x->card->zap_context($silent_zapata_context); + } else { + $a20x->card->zap_context("from-zaptel"); + } + $a20x->card->zap_group("0"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); + } + } + if($num_analog_devices_total!=0){ + print("\nAnalog card configuration complete\n\n"); + if( $silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } + +} + diff --git a/util/wancfg_zaptel/wancfg_zaptel.pl~ b/util/wancfg_zaptel/wancfg_zaptel.pl~ new file mode 100755 index 0000000..5efc256 --- /dev/null +++ b/util/wancfg_zaptel/wancfg_zaptel.pl~ @@ -0,0 +1,2311 @@ +#!/usr/bin/perl +# config-zaptel.pl +# Sangoma Zaptel/TDM API/SMG Configuration Script. +# +# Copyright (c) 2006, Sangoma Technologies Inc. +# +# 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. +# ---------------------------------------------------------------------------- +# Jan 02 2008 2.10 David Yat Sin Added option for BRI master clock +# Dec 15 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 +# Nov 29 2007 2.8 David Yat Sin Support for BRI cards on Trixbox +# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option +# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode +# Jul 20, 2007 2.5 David Yat Sin silent option +# Jun 13, 2007 Yuan Shen SS7 support +# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major +# changes to script. +# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl +# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong +# context +# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards +# Oct 13, 2006 David Yat Sin Added --opermode and --law option +# Oct 12, 2006 David Yat Sin Initial version +# ============================================================================ + +system('clear'); +print "\n###################################################################"; +print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; +print "\n# v2.10 #"; +print "\n# Sangoma Technologies Inc. #"; +print "\n# Copyright(c) 2007. #"; +print "\n###################################################################\n\n"; + +use strict; +#use warnings; +#use diagnostics; +use Card; +use A10x; +use A10u; +use A20x; +use A50x; + + +my $FALSE = 1; +my $TRUE = 0; +my $zaptelprobe=' '; + +my $etc_dir=""; +my $include_dir=""; +my $module_list=""; +my $module_load=""; +my $module_unload=""; +my $os_type_name=""; +my $dchan_str="dchan"; + +my $os_type_list=`sysctl -a |grep ostype`; +if ($os_type_list =~ m/Linux/){ + $os_type_name="Linux"; + $etc_dir="/etc"; + $module_load="modprobe"; + $module_unload="modprobe -r"; + $module_list="modprobe -l"; + $include_dir="/usr/include"; +}elsif ($os_type_list =~ m/FreeBSD/){ + $os_type_name="FreeBSD"; + $etc_dir="/usr/local/etc"; + $module_load="kldload"; + $module_unload="kldunload"; + $module_list="kldstat"; +}else{ + print("Failed to determine OS type\n"); + print("Exiting...\n"); + exit(1); +} + + +my $no_boot=$FALSE; +my $startup_string=""; +my $cfg_string=""; +my $first_cfg=1; +my $zaptel_conf=""; +my $zapata_conf=""; +my $bri_conf=""; +my $woomera_conf=""; +my $devnum=1; +my $current_zap_span=1; +my $current_tdmapi_span=1; +#my $current_bri_span=1; +my $current_zap_channel=1; +my $num_analog_devices=0; +my $num_analog_devices_total=0; +my $num_bri_devices=0; +my $num_bri_devices_total=0; +my $num_digital_devices=0; +my $num_digital_devices_total=0; +my $num_ss7_config=0; +my $num_zaptel_config=0; +my $line_media=''; +my $max_chans=0; +my $ss7_tdmvoicechans=''; +my $ss7_array_length=0; + + + +my $device_has_hwec=$FALSE; +my $device_has_normal_clock=$FALSE; +my @device_normal_clocks=("0"); +my @woomera_groups=("0"); +my $bri_device_has_master_clock=$FALSE; + +my $is_tdm_api=$FALSE; + +my $def_femedia=''; +my $def_feframe=''; +my $def_feclock=''; +my $def_bri_option=''; +my $def_signalling=''; +my $def_switchtype=''; +my $def_zapata_context=''; +my $def_woomera_context=''; +my $def_zapata_group=''; +my $def_te_ref_clock=''; +my $def_tdmv_dchan=0; +my $def_bri_group=''; +my $def_felcode=''; +my $def_feframe=''; +my $def_te_sig_mode=''; + +my $def_hw_dtmf="YES"; +my $def_tdm_law=''; + + +my @silent_femedias; +my @silent_feframes; +my @silent_felcodes; +my @silent_tdm_laws; +my @silent_feclocks; +my @silent_signallings; +my @silent_pri_switchtypes; +my @silent_zapata_contexts; +my @silent_woomera_contexts; +my @silent_zapata_groups; +my @silent_silent_te_sig_modes; + + +my $silent_femedia="T1"; +my $silent_feframe="ESF"; +#my $silent_feframe_e1="CRC4"; + +my $silent_felcode="B8ZS"; +my $silent_tdm_law="MULAW"; + + +my $silent_feclock="NORMAL"; +my $silent_signalling="PRI CPE"; +my $silent_pri_switchtype="national"; +my $silent_zapata_context="from-pstn"; +my $silent_woomera_context="from-pstn"; +my $silent_zapata_group="0"; +my $silent_te_sig_mode='CCS'; + +my $def_bri_country="europe"; +my $def_bri_operator="etsi"; +my $def_bri_conn_type="Point to multipoint"; + +my $is_trixbox = $FALSE; +my $silent = $FALSE; +my $config_zaptel = $TRUE; +my $config_zapata = $TRUE; +my $is_smg = $FALSE; + +my $tdm_api_span_num=0; +my $zaptel_installed=$FALSE; +my $modprobe_list=`$module_list`; + + +read_args(); +check_zaptel(); +my $current_dir=`pwd`; +chomp($current_dir); +my $cfg_dir='tmp_cfg'; +my $curdircfg="$current_dir"."/"."$cfg_dir"; + +unless ( -d $curdircfg ) { + $curdircfg = "mkdir " . $curdircfg; + system ($curdircfg); +} + + +my $debug_info_file="$current_dir/$cfg_dir/debug_info"; +my @hwprobe=`wanrouter hwprobe verbose`; + +my $wanpipe_conf_dir="$etc_dir/wanpipe"; +my $asterisk_conf_dir="$etc_dir/asterisk"; + +my $wanrouter_rc_template="$current_dir/templates/wanrouter.rc.template"; + +my $zaptel_conf_template="$current_dir/templates/zaptel.conf"; +my $zaptel_conf_file="$current_dir/$cfg_dir/zaptel.conf"; +my $zaptel_conf_file_t="$etc_dir/zaptel.conf"; + +my $zapata_conf_template="$current_dir/templates/zapata.conf"; +my $zapata_conf_file="$current_dir/$cfg_dir/zapata.conf"; +my $zapata_conf_file_t="$asterisk_conf_dir/zapata.conf"; + +my $bri_conf_template="$current_dir/templates/smg_bri.conf"; +my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; +my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; + +my $woomera_conf_template="$current_dir/templates/woomera.conf"; +my $woomera_conf_file="$current_dir/$cfg_dir/woomera.conf"; +my $woomera_conf_file_t="$asterisk_conf_dir/woomera.conf"; + +my $date=`date +%F`; +chomp($date); +my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; + +set_zaptel_hwhdlc(); +prepare_files(); +config_t1e1(); +config_bri(); +config_analog(); +summary(); +apply_changes(); +config_boot(); +config_ztcfg_start(); +config_smg_ctrl_start(); +clean_files(); +print "Sangoma cards configuration complete, exiting...\n\n"; + + +#######################################FUNCTIONS################################################## + + +sub set_zaptel_hwhdlc{ + if ((system("grep hdlc_hard_xmit '$include_dir/zaptel/zaptel.h'>/dev/null 2>/dev/null")==0)){ + $dchan_str="hardhdlc"; + } +} + +sub config_boot{ + if($no_boot==$TRUE){ + return; + } + my $script_name="wanrouter"; + my $current_run_level=3; + my $zaptel_start_level=9; + my $zaptel_stop_level=92; + my $network_start_level=10; + my $wanrouter_start_level=8; + my $wanrouter_stop_level=91; + my $smg_ctrl_start_level=11; + my $command=''; + my $rc_dir=$etc_dir; + + if ($os_type_list =~ m/FreeBSD/){ + return; + } + my $res=`cat $etc_dir/inittab |grep id`; + if ($res =~ /id:(\d+):initdefault/){ + $current_run_level=$1; + print "Current boot level is $current_run_level\n"; + } else { + print "Warning: Failed to determine init boot level, assuming 3\n"; + $current_run_level=3; + } + + + print "\nWanrouter boot scripts configuration...\n\n"; + print "Removing existing $script_name boot scripts..."; + $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; + if(system($command) == 0){ + print "OK\n"; + } else { + print "Not installed\n"; + } + if($num_ss7_config!=0){ + $script_name="smgss7_init_ctrl"; + } + + print ("Would you like $script_name to start on system boot?\n"); + my $res='YES'; + if($silent==$FALSE){ + $res= &prompt_user_list("YES","NO",""); + } + + if ( $res eq 'YES'){ + #examine system bootstrap files + $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$rc_dir; + } else { + $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $rc_dir=$etc_dir."/rc.d"; + } else { + print "Failed to locate boostrap directory\n"; + print "wanrouter boot scripts will not be installed\n"; + return; + } + } + + if($zaptel_installed==$TRUE){ + print "Verifying Zaptel boot scripts..."; + #find zaptel start scripts + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; + $res=`$command`; + if ($res =~ /.*S(\d+)zaptel/){ + $zaptel_start_level=$1; + print "Enabled (level:$zaptel_start_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_start_level"; + } + } else { + print "Not installed\n"; + $zaptel_start_level=0; + } + + #find zaptel stop scripts + print "Verifying Zaptel shutdown scripts..."; + $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find ".$rc_dir."/rc6.d/*zaptel"; + $res=`$command`; + if ($res =~ /.*K(\d+)zaptel/){ + $zaptel_stop_level=$1; + print "Enabled (level:$zaptel_stop_level)\n"; + } else { + print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; + } + } else { + print "Not installed\n"; + $zaptel_stop_level=0; + } + if ($zaptel_start_level != 0){ + $wanrouter_start_level=$zaptel_start_level-1; + } + if ($zaptel_stop_level != 0){ + $wanrouter_stop_level=$zaptel_stop_level-1; + } + } + + my $wanrouter_start_script=''; + if($wanrouter_start_level < 10){ + $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; + } else { + $wanrouter_start_script="S".$wanrouter_start_level.$script_name; + } + my $wanrouter_stop_script=''; + if($wanrouter_stop_level < 10){ + $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; + } else { + $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; + } + + $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; + if(system($command) !=0){ + $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; + if(system($command) !=0){ + print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; + print "$script_name boot scripts not installed\n"; + return; + } + } + print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; + if(system($command) !=0){ + print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; + print "$script_name start scripts not installed\n"; + return; + } + } + + print "Enabling $script_name shutdown scripts ...(level:$wanrouter_stop_level)\n"; + @run_levels= ("0","1","6"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; + if(system($command) !=0){ + print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; + print "$script_name stop scripts not installed\n"; + return; + } + } + + if($num_bri_devices != 0){ + #smg_ctrl must start after network + print "Verifying Network boot scripts..."; + $command="find $rc_dir/rc".$current_run_level.".d/*network >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*network"; + $res=`$command`; + if ($res =~ /.*S(\d+)network/){ + $network_start_level=$1; + print "Enabled (level:$network_start_level)\n"; + } else { + print "\nfailed to parse network boot level, assuming $network_start_level"; + } + } else { + print "Not installed\n"; + $network_start_level=0; + } + if ($network_start_level != 0 && $network_start_level > $zaptel_start_level){ + $smg_ctrl_start_level=$network_start_level+1; + print "Enabling smg_ctrl start scripts...(level:$smg_ctrl_start_level)\n"; + $command="install -D -m 755 /usr/sbin/smg_ctrl $rc_dir/init.d/smg_ctrl"; + if(system($command) !=0){ + print "Failed to install smg_ctrl start scripts to $rc_dir/init.d/smg_ctrl"; + print "smg_ctrl start scripts not installed"; + return; + } + my $smg_ctrl_start_script=''; + if($smg_ctrl_start_level < 10){ + $smg_ctrl_start_script="S0".$smg_ctrl_start_level."smg_ctrl"; + } else { + $smg_ctrl_start_script="S".$smg_ctrl_start_level."smg_ctrl"; + } + print "Enabling smg_ctrl boot scripts ...(level:$smg_ctrl_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/smg_ctrl ".$rc_dir."/rc".$run_level.".d/".$smg_ctrl_start_script; + if(system($command) !=0){ + print "Failed to install smg_ctrl init script to $rc_dir/rc$run_level.d/$smg_ctrl_start_script\n"; + print "smg_ctrl start scripts not installed\n"; + return; + } + } + } + + } + + } + +} + + +sub config_ztcfg_start{ + if ($num_zaptel_config ==0 || $silent==$TRUE){ + return; + } + my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; + if (system($command) != 0){ + #Zaptel init scripts not installed, prompt for wanpipe_zaptel_start_script + print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + exec_command("cp -f $current_dir/templates/zaptel_cfg_script $wanpipe_conf_dir/scripts/start"); + } + } +} + +sub config_smg_ctrl_start{ + if($num_bri_devices == 0){ + return; + } + print ("Would you like smg_ctrl to start/stop on wanrouter start?\n"); + if (&prompt_user_list("YES","NO","") eq 'YES'){ + #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite + my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; + } else { + $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; + } + + if (system($command) == 0){ + print "smgbri start script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + + $command="cp -f ".$current_dir."/templates/smgbri_stop_script ".$wanpipe_conf_dir."/scripts/stop"; + if (system($command) == 0){ + print "smgbri start script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + } +} + +sub check_zaptel{ + if ($modprobe_list =~ /zaptel.ko/){ + $zaptel_installed=$TRUE; + } +} + +sub apply_changes{ + my $asterisk_command=''; + my $bri_command=''; + my $asterisk_restart=$FALSE; + my $res=''; + + system('clear'); + + if($silent==$TRUE){ + $res="Stop now"; + }elsif($is_tdm_api==$TRUE){ + print "\n Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", + "Do not save cfg: Exit", + ""); + }else{ + print "\nZaptel and Wanpipe configuration complete: choose action\n"; + $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", + "Save cfg: Restart Asterisk & Wanpipe when convenient", + "Save cfg: Stop Asterisk & Wanpipe now", + "Save cfg: Stop Asterisk & Wanpipe when convenient", + "Do not save cfg: Exit", + ""); + } + + + if ($res =~ m/Exit/){ + print "No changes made to your configuration files\n"; + exit 0; + } + if ($res =~ m/now/){ + $asterisk_command='stop now'; + } else { + $asterisk_command='stop when convenient'; + } + + if ($res =~ m/Restart/){ + $asterisk_restart=$TRUE; + } else { + $asterisk_restart=$FALSE; + } + + if ($is_trixbox==$TRUE){ + exec_command("amportal stop"); + unload_zap_modules(); + } elsif ($is_tdm_api==$FALSE ){ + if (`(pidof asterisk)` != 0 ){ + print "\nStopping Asterisk...\n"; + exec_command("asterisk -rx \"$asterisk_command\""); + sleep 2; + while (`(pidof asterisk)` != 0 ){ + if ($asterisk_command eq "stop now"){ + print "Failed to stop asterisk using command: \'$asterisk_command\' \n"; + my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes"); + my $res=&prompt_user_list(@options,""); + + if ( $res =~ m/Force Stop/){ + execute_command("kill -KILL \$(pidof asterisk)"); + } elsif ( $res =~ m/Exit/ ){ + exit(1); + } else { + print "Waiting for asterisk to stop...\n"; + sleep 5; + exec_command("asterisk -rx \"$asterisk_command\""); + } + } else { + #stop when convenient option was selected + print "Waiting for asterisk to stop...\n"; + sleep 3; + } + } + + + + + + }else { + print "\nAsterisk is not running...\n"; + } + + } + + if($num_bri_devices != 0){ + exec_command("/usr/sbin/smg_ctrl stop"); + } + + print "\nStopping Wanpipe...\n"; + exec_command("wanrouter stop all"); + + if ($zaptel_installed==$TRUE){ + if($is_tdm_api==$FALSE){ + print "\nUnloading Zaptel modules...\n"; + unload_zap_modules(); + } + } + + print "\nRemoving old configuration files...\n"; + + exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); + + gen_wanrouter_rc(); + + print "\nCopying new Wanpipe configuration files...\n"; + copy_config_files(); + if($num_bri_devices != 0){ + print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; + exec_command("cp -f $bri_conf_file $bri_conf_file_t"); + exec_command("cp -f $woomera_conf_file $woomera_conf_file_t"); + } + + if ($zaptel_installed==$TRUE){ + if($config_zaptel==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; + exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); + } + } + } + + if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ + if ($num_zaptel_config !=0){ + print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; + exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); + } + } + + if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ + print "\nStarting Wanpipe...\n"; + exec_command("wanrouter start"); + + if($num_bri_devices != 0){ + print "Loading SMG BRI...\n"; + sleep 2; + exec_command("/usr/sbin/smg_ctrl start"); + } + +# if ( ! -e "/$wanpipe_conf_dir/scripts/start" & $is_trixbox==$FALSE && $is_smg==$FALSE ){ + if ($num_zaptel_config != 0){ + print "Loading Zaptel...\n"; + sleep 2; + exec_command("ztcfg -v"); +# print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); +# if (&prompt_user_list("YES","NO","") eq 'YES'){ +# exec_command("cp -f $wanpipe_conf_dir/samples/wanpipe_zaptel_start $wanpipe_conf_dir/scripts/start"); +# } + } + if ($is_trixbox==$TRUE){ + print "\nStarting Amportal...\n"; + exec_command("amportal start"); + sleep 2; + }elsif($config_zapata==$TRUE){ + print "\nStarting Asterisk...\n"; + exec_command("asterisk"); + sleep 2; + + print "\nListing Asterisk channels...\n\n"; + exec_command("asterisk -rx \"zap show channels\""); + print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; + }else{ + } + } + print "\nWanrouter start complete...\n"; +} + + + +sub save_debug_info{ + my $version=`wanrouter version`; + chomp($version); + + my $uname=`uname -a`; + chomp($uname); + + my $issue=''; + + if ($os_type_list =~ m/Linux/){ + $issue=`cat $etc_dir/issue`; + chomp($issue); + } + + my $debug_info="\n"; + $debug_info.="===============================================================\n"; + $debug_info.=" SANGOMA DEBUG INFO FILE \n"; + $debug_info.=" Generated on $date \n"; + $debug_info.="===============================================================\n"; + + $debug_info.="\n\nwanrouter hwprobe\n"; + $debug_info.="@hwprobe\n"; + $debug_info.="\nwanrouter version\n"; + $debug_info.="$version\n"; + $debug_info.="\nKernel \"uname -a\"\n"; + $debug_info.="$uname\n"; + if ($os_type_list =~ m/Linux/){ + $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; + $debug_info.="$issue\n"; + } + $debug_info.="EOF\n"; + + open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; + print FH $debug_info; + close (FH); + exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); +} + +sub get_zapata_context{ + my ($card_model,$card_port)=@_; + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("Select dialplan context for AFT-A%s on port %s\n", $card_model, $card_port); + my $res = &prompt_user_list(@options,$def_zapata_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_zapata_context); + } + + $context=$res_context; + }elsif($res eq $def_zapata_context){ + $context=$def_zapata_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + $context=$silent_zapata_context; + } + $def_zapata_context=$context; + return $context; +} + + +sub get_woomera_context{ + my ($group,$card_model,$card_port,$bri_type)=@_; + + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($bri_type eq 'bri_nt'){ + @options = ("from-internal","Custom"); + } elsif ($bri_type eq 'bri_te'){ + @options = ("from-pstn","Custom"); + } + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("\nSelect dialplan context for group:%d\n", $group); + my $res = &prompt_user_list(@options,$def_woomera_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_woomera_context); + } + + $context=$res_context; + }elsif($res eq $def_woomera_context){ + $context=$def_woomera_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + $context=$silent_woomera_context; + } + $def_woomera_context=$context; + return $context; +} + + + +sub gen_wanrouter_rc{ + #update wanpipe startup sequence + my $rcfile=""; + if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { + open (FH,"$wanrouter_rc_template"); + } + while () { + $rcfile .= $_; + } + close (FH); + open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); + $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; + print FH $rcfile; + close (FH); +} + +sub prepare_files{ + + if ($is_trixbox==$TRUE){ + $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; + $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; + $zapata_conf_file_t="$asterisk_conf_dir/zapata-auto.conf"; + } + + if ($silent==$FALSE){ + if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ + print "Would you like to generate $zapata_conf_file_t\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $config_zapata = $FALSE; + } + } + } + +#remove temp files + my $tmp_cfg_dir="$current_dir"."/"."$cfg_dir"; + if ( -d "$current_dir"."/"."$cfg_dir") { + exec_command("rm -f $current_dir/$cfg_dir/*"); + } +#backup existing configuration files + if ( -f $zaptel_conf_file_t ) { + exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); + } + + if ( -f $zapata_conf_file_t ) { + exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); + } +} + +sub clean_files{ + exec_command("rm -rf $current_dir/$cfg_dir"); +} + + +sub write_zapata_conf{ + my $zp_file=""; + open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + + $zp_file.=$zapata_conf; + + open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; + print FH $zp_file; + close(FH); +} + +sub copy_config_files{ + my @wanpipe_files = split / /, $cfg_string; + exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc $wanpipe_conf_dir"); + foreach my $wanpipe_file (@wanpipe_files) { + exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf $wanpipe_conf_dir"); + } +} + +sub unload_zap_modules{ + my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); + foreach my $module (@modules_list) { + if ($modprobe_list =~ m/$module/){ + exec_command("$module_unload $module"); + } + } +} + +sub write_zaptel_conf{ + my $zp_file=""; + open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; + while () { + $zp_file .= $_; +} + close (FH); + $zp_file=$zp_file.$zaptel_conf; + open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; + print FH $zp_file; + close(FH); +} + +sub summary{ + if($devnum==1){ + system('clear'); + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); + exit 0; + }else{ + if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ + write_zaptel_conf(); + } + if ($num_bri_devices != 0 ){ + write_bri_conf(); + write_woomera_conf(); + } + if ($config_zapata==$TRUE){ + write_zapata_conf(); + } + save_debug_info(); + system('clear'); + my $file_list = 1; + print "\n###################################################################"; + print "\n# SUMMARY #"; + print "\n###################################################################\n\n"; + + print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); + print(" $num_bri_devices_total ISDN BRI port(s) detected, $num_bri_devices configured\n"); + print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); + + print "\nConfigurator has created the following files:\n"; + print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; + $file_list++; + + if ($num_bri_devices != 0){ + print "\t$file_list. sangoma_brid config file $wanpipe_conf_dir/smg_bri\n"; + $file_list++; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; + } + + if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ + print "\n\nYour original configuration files will be saved to:\n"; + $file_list=1; + } + + if ($num_zaptel_config != 0){ + print "\t$file_list. $zaptel_conf_file_t.bak \n"; + $file_list++; + } + if ($config_zapata==$TRUE){ + print "\t$file_list. $zapata_conf_file_t.bak \n\n"; + } + + print "\nYour configuration has been saved in $debug_tarball.\n"; + print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } +} + + +sub exec_command{ + my @command = @_; + if (system(@command) != 0 ){ + print "Error executing command:\n@command\n\n"; + print "Would you like to continue?\n"; + if(&prompt_user_list("No - exit", "YES", "No") eq 'YES'){ + return $?; + } else { + exit $?; + } + } + return $?; +} + +sub prompt_user{ + my($promptString, $defaultValue) = @_; + if ($defaultValue) { + print $promptString, "def=\"$defaultValue\": "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $_ = ; # get the input from STDIN (presumably the keyboard) + chomp; + if ("$defaultValue") { + return $_ ? $_ : $defaultValue; # return $_ if it has a value + } else { + return $_; + } +} + +sub prompt_user_list{ + my @list = @_; + my $defaultValue = @list[$#list]; + + my $i; + my $valid = 0; + for $i (0..$#list-1) { + printf(" %s\. %s\n",$i+1, @list[$i]); + } + while ($valid == 0){ + my $list_sz = $#list; + print "[1-$list_sz"; + if ( ! $defaultValue eq ''){ + print ", ENTER=\'$defaultValue\']:"; + }else{ + print "]:"; + } + $| = 1; + $_ = ; + chomp; + if ( $_ eq '' & ! $defaultValue eq ''){ + print "\n"; + return $defaultValue; + } + + if ( $_ =~ /(\d+)/ ){ + if ( $1 > $list_sz) { + print "\nError: Invalid option, input a value between 1 and $list_sz \n"; + } else { + print "\n"; + return @list[$1-1] ; + } + } else { + print "\nError: Invalid option, input an integer\n"; + } + } +} + +sub read_args { + my $arg_num; + foreach $arg_num (0 .. $#ARGV) { + $_ = $ARGV[$arg_num]; + if( /^--trixbox$/){ + $is_trixbox=$TRUE; + }elsif ( /^--tdm_api/){ + $is_tdm_api=$TRUE; + }elsif ( /^--smg$/){ + $is_smg=$TRUE; + }elsif ( /^--no_boot$/){ + $no_boot=$TRUE + }elsif ( /^--silent$/){ + $silent=$TRUE; + }elsif ( /^--no-zapata$/){ + $config_zapata=$FALSE; + }elsif ( /^--no-zaptel$/){ + $config_zaptel=$FALSE; + }elsif ( $_ =~ /--fe_media=(\w+)/){ + $silent_femedia=$1; + if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ + printf("Invalid value for fe_media, should be T1/E1\n"); + exit(1); + } else { + push(@silent_femedias, $silent_femedia); + } + }elsif ( $_ =~ /--fe_lcode=(\w+)/){ + $silent_felcode=$1; + if(!($silent_felcode eq 'B8ZS' || $silent_felcode eq 'HDB3' || $silent_felcode eq 'AMI')){ + printf("Invalid value for fe_lcode, should be B8ZS/HDB3/AMI \n"); + exit(1); + } else { + push(@silent_felcodes, $silent_felcode); + } + }elsif ( $_ =~ /--fe_frame=(\w+)/){ + $silent_feframe=$1; + if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ + printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); + exit(1); + } else { + push(@silent_feframes, $silent_feframe); + } + }elsif ( $_ =~ /--tdm_law=(\w+)/){ + $silent_tdm_law=$1; + if(!($silent_tdm_law eq 'MULAW' || $silent_tdm_law eq 'ALAW')){ + printf("Invalid value for tdm_law, should be MULAW/ALAW\n"); + exit(1); + } else { + push(@silent_tdm_laws, $silent_tdm_law); + } + }elsif ( $_ =~ /--fe_clock=(\w+)/){ + $silent_feclock=$1; + if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ + printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); + exit(1); + } else { + push(@silent_feclocks, $silent_feclock); + } + }elsif ( $_ =~ /--signalling=(\w+)/){ + my $tmp_signalling=$1; + if ($tmp_signalling eq 'em'){ + $silent_signalling="E & M"; + }elsif ($tmp_signalling eq 'em_w'){ + $silent_signalling="E & M Wink"; + }elsif ($tmp_signalling eq 'pri_cpe'){ + $silent_signalling="PRI CPE"; + }elsif ($tmp_signalling eq 'pri_net'){ + $silent_signalling="PRI NET"; + }elsif ($tmp_signalling eq 'fxs_ls'){ + $silent_signalling="FXS - Loop Start"; + }elsif ($tmp_signalling eq 'fxs_gs'){ + $silent_signalling="FXS - Ground Start"; + }elsif ($tmp_signalling eq 'fxs_ks'){ + $silent_signalling="FXS - Kewl Start"; + }elsif ($tmp_signalling eq 'fxo_ls'){ + $silent_signalling="FXO - Loop Start"; + }elsif ($tmp_signalling eq 'fxo_gs'){ + $silent_signalling="FXO - Ground Start"; + }elsif ($tmp_signalling eq 'fxo_ks'){ + $silent_signalling="FXO - Kewl Start"; + }else{ + printf("Invalid option for --signalling, options are\n"); + printf("\t pri_cpe/pri_net/em/em_w\n"); + printf("\t em/em_w\n"); + printf("\t fxo_ls/fxo_gs/fxo_ks\n"); + printf("\t fxs_ls/fxs_gs/fxs_ks\n"); + exit(1); + } + + push(@silent_signallings, $silent_signalling); + + }elsif ( $_ =~ /--pri_switchtype=(\w+)/){ + my $tmp_switchtype=$1; + if ($tmp_switchtype eq 'national'){ + $silent_pri_switchtype="national" + }elsif ($tmp_switchtype eq 'dms100'){ + $silent_pri_switchtype="dms100" + }elsif ($tmp_switchtype eq '4ess'){ + $silent_pri_switchtype="4ess" + }elsif ($tmp_switchtype eq '5ess'){ + $silent_pri_switchtype="5ess" + }elsif ($tmp_switchtype eq 'euroisdn'){ + $silent_pri_switchtype="euroisdn" + }elsif ($tmp_switchtype eq 'ni1'){ + $silent_pri_switchtype="ni1" + }elsif ($tmp_switchtype eq 'qsig'){ + $silent_pri_switchtype="qsig" + } else { + printf("Invalid option for --pri_switchtype, options are\n"); + printf("\t national/dms100/4ess/5ess/euroisdn/ni1/qsig"); + exit(1); + } + push(@silent_pri_switchtypes, $silent_pri_switchtype); + }elsif ( $_ =~ /--conf_dir=(.*)/){ + $etc_dir=$1; + if (! -d $etc_dir){ + printf("Error: directory $1 does not exist\n"); + exit(1); + } + } + } + @silent_femedias = reverse(@silent_femedias); + @silent_feframes = reverse(@silent_feframes); + @silent_felcodes = reverse(@silent_felcodes); + @silent_tdm_laws = reverse(@silent_tdm_laws); + @silent_feclocks = reverse(@silent_feclocks); + @silent_signallings = reverse(@silent_signallings); + @silent_pri_switchtypes = reverse(@silent_pri_switchtypes); + +# DAVIDY: Implement those later +# @silent_zapata_contexts = reverse(@silent_zapata_contexts); +# @silent_woomera_contexts = reverse(@silent_woomera_contexts); +# @silent_zapata_groups = reverse(@silent_zapata_groups); +# @silent_silent_te_sig_modes = reverse(@silent_te_sig_modes); + + if ($is_trixbox==$TRUE){ + print "\nGenerating configuration files for Trixbox\n"; + } + if ($is_smg==$TRUE){ + print "\nGenerating configuration files for Sangoma Media Gateway\n"; + } + if ($is_tdm_api==$TRUE){ + $config_zapata = $FALSE; + } + +} + +#------------------------------BRI FUNCTIONS------------------------------------# +sub get_bri_country { + $def_bri_country = "europe"; + return $def_bri_country; +} + +sub get_bri_group{ + my $group; + my $res_group=&prompt_user("\nInput the group for this port\n",$def_bri_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ + print "Invalid group, input an integer greater than 0\n"; + $res_group=&prompt_user("Input the group for this port",$def_bri_group); + } + $group=$res_group; + $def_bri_group=$group; + return $def_bri_group; +} + + +sub get_bri_operator { +#warning returning ETSI + $def_bri_operator = "etsi"; + return $def_bri_operator; + + + + my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", + "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", + "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); + + my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); + + my $res = &prompt_user_list(@options,$def_switchtype); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_operator=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + +sub write_bri_conf{ + my $bri_file=""; + open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; + while () { + $bri_file .= $_; + } + close (FH); + $bri_file=$bri_file.$bri_conf; + open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; + print FH $bri_file; + close(FH); +} + +sub write_woomera_conf{ + my $woomera_file=""; + open(FH, "$woomera_conf_template") or die "cannot open $woomera_conf_template"; + while () { + $woomera_file .= $_; + } + close (FH); + $woomera_file=$woomera_file.$woomera_conf; + open(FH, ">$woomera_conf_file") or die "cannot open $woomera_conf_file"; + print FH $woomera_file; + close(FH); +} + + +sub get_bri_conn_type{ + my $conn_type; + + my @options = ( "Point to multipoint", "Point to point"); + my @options_val = ("point_to_multipoint", "point_to_point"); + + my $res = &prompt_user_list(@options,$def_bri_conn_type); + + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_bri_conn_type=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid BRI connection type\n"; + exit 1; +} + + + + +sub config_bri{ + if($is_smg!=$TRUE && $is_trixbox==$FALSE){ + return; + } + if ($silent==$TRUE){ + return; + } + my $a50x; + if (!$first_cfg) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring ISDN BRI cards [A500]\n"; + print "------------------------------------\n"; + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ + $skip_card=$FALSE; + if ($1 eq '500'){ + my $card = eval {new Card(); } or die ($@); + + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + + my $hwec=0; + if($6 gt 0){ + $hwec=1; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + + if ($card->card_model eq '500'){ + $num_bri_devices_total++; + if($5 eq '1'){ + $bri_device_has_master_clock=$FALSE; + } + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + +select_bri_option: + print "\nWould you like to configure AFT-A$1 port $5 on slot:$3 bus:$4\n"; + my @options=("YES", "NO", "Exit"); + $def_bri_option=&prompt_user_list(@options,$def_bri_option); + if($def_bri_option eq 'YES'){ + $skip_card=$FALSE; + $bri_conf.="\n;Sangoma AFT-A$1 port $5 [slot:$3 bus:$4 span:$current_tdmapi_span]"; + }elsif($def_bri_option eq 'NO'){ + $skip_card=$TRUE; + }else{ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } else { + goto select_bri_option; + } + } + if ($skip_card==$FALSE){ + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + $a50x = eval {new A50x(); } or die ($@); + $a50x->card($card); + $a50x->fe_line($5); + $devnum++; + $num_bri_devices++; + $card->tdmv_span_no($current_tdmapi_span); + $current_tdmapi_span++; +# $a50x->gen_wanpipe_conf(); + }else{ + print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; + prompt_user("Press any key to continue"); + } + + } + } + }elsif (($dev =~ /(\d+):NT/ | + $dev =~ /(\d+):TE/ )& + $skip_card==$FALSE ){ + + + my $context=""; + my $group=""; + my $bri_pos=$a50x->card->tdmv_span_no; + + printf("\nConfiguring port %d on AFT-A%d [slot:%d bus:%d span:%d]\n", $a50x->fe_line(), $a50x->card->card_model(), $a50x->card->pci_slot(), $a50x->card->pci_bus(), $current_tdmapi_span-1); + printf("\nSelect connection type for port %d\n", $a50x->fe_line()); + my $conn_type=get_bri_conn_type(); + my $country=get_bri_country(); + my $operator=get_bri_operator(); + if($is_trixbox==$TRUE){ + if ( $dev =~ /(\d+):NT/ ){ + $context="from-internal"; + $group=1; + } else { + $context="from-zaptel"; + $group=0; + } + } else { + $group=get_bri_group(); + #if a context has already been assigned to this group, do not prompt for options + foreach my $f_group (@woomera_groups) { + if($f_group eq $group){ + $context="WOOMERA_NO_CONFIG"; + } + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + if ( $dev =~ /(\d+):NT/ ){ + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_nt'); + } else { + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_te'); + } + push(@woomera_groups, $group); + + } + } + $a50x->gen_wanpipe_conf(); + if ( $dev =~ /(\d+):NT/ ){ + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_nt", $group, $country, $operator, $conn_type); + } else { + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + $woomera_conf.=$a50x->gen_woomera_conf($group, $context); + } + + } + } +# prompt_user("Press any key to continue"); + if($num_bri_devices_total!=0){ + print("\nISBN BRI card configuration complete\n\n"); + prompt_user("Press any key to continue"); + } else { + print("\nNo Sangoma ISDN BRI cards detected\n\n"); + prompt_user("Press any key to continue"); + + } +} + + + + + +#------------------------------T1/E1 FUNCTIONS------------------------------------# + +sub get_te_ref_clock{ + my @list_normal_clocks=@_; + my @f_list_normal_clocks; + my $f_port; + foreach my $port (@list_normal_clocks) { + if ($port eq '0'){ + $f_port = "Free run"; + } else { + $f_port = "Port ".$port; + } + push(@f_list_normal_clocks, $f_port); + } + + my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); + my $i; + + for $i (0..$#f_list_normal_clocks){ + if ( $res eq @f_list_normal_clocks[$i] ){ + return @list_normal_clocks[$i]; + } + } + + print "Internal error: Invalid reference clock\n"; + exit 1; + +} + + +sub prompt_user_hw_dchan{ + my ($card_model, $port, $port_femedia) = @_; + my $res_dchan=''; + my $dchan; + + printf("Hardware HDLC can be performed on the data channel.\n"); +prompt_hw_dchan: + my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); + while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ + print "Invalid channel, input an integer (0 for unused).\n"; + $res_dchan=&prompt_user("Select the data channel","0"); + } + if ( $res_dchan < 0){ + printf("Error: channel cannot have negative value\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ( $port_femedia eq 'T1' && $res_dchan > 24){ + printf("Error: only 24 channels available on T1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + }elsif ($port_femedia eq 'E1' && $res_dchan > 31){ + printf("Error: only 31 channels available on E1\n"); + $res_dchan=''; + goto prompt_hw_dchan; + } + if ($res_dchan == 0){ + printf("HW HDLC channel not used\n"); + }else{ + printf("HW HDLC channel set to:%d\n", $res_dchan); + } + return $res_dchan; +} + + + +sub get_zapata_group{ + my ($card_model,$card_port,$context)=@_; + my $group=''; + if($is_trixbox==$TRUE){ + if($context eq "from-zaptel"){ + $group=0; + return $group; + }elsif($context eq "from-internal"){ + $group=1; + return $group; + }else{ + print "Internal error:invalid group for Trixbox\n"; + } + }else{ + if($context eq "from-pstn"){ + $group=0; + }elsif($context eq "from-internal"){ + $group=1; + }else{ + my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); + while(length($res_group)==0 |!($res_group =~/(\d+)/)){ + print "Invalid group, input an integer.\n"; + $res_group=&prompt_user("Input the group for this port",$def_zapata_group); + } + $group=$res_group; + $def_zapata_group=$group; + } + } + + return $group; +} + + + +sub prompt_hw_dtmf { +#HW DTMF not supported in the 3.2 drivers +# return "NO"; + print("Would you like to enable hardware DTMF detection?\n"); + my @options = ("YES","NO"); + $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); + return $def_hw_dtmf; +} + +sub prompt_tdm_law { + print("Which codec will be used?\n"); + my @options = ("MULAW - North America","ALAW - Europe"); + my @options_val = ("MULAW", "ALAW"); + my $res = &prompt_user_list(@options, $def_tdm_law); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_tdm_law=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid TDM LAW type\n"; + exit 1; +} + + +sub get_pri_switchtype { + my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); + my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); + my $res = &prompt_user_list(@options,$def_switchtype); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_switchtype=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid PRI switchtype\n"; + exit 1; +} + + +sub gen_ss7_voicechans{ + my @ss7_array = @_; + my $T1CHANS = pop(@ss7_array); + my $count = @ss7_array; + my $output =''; + my $chan_in = 1; + my $chan_de = 0; + my $flag = 0; + my $i = 0; + my $j = 0; + + while($i < $count){ + $j = $i + 1; + if ($ss7_array[$i] > 2 && $i == 0){ + $chan_de = $ss7_array[$i] - 1; + $output .= "1-$chan_de"; + $flag = 1; + }elsif ($ss7_array[$i] == 2 && $i == 0){ + $output .= "1"; + $flag = 1; + } + + if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ + goto Incrementing; + }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ + goto Incrementing; + } + + if ($i < ($count-1)){ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < ($ss7_array[$j]-1)){ + $chan_de = $ss7_array[$j] - 1; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$chan_in"; + }else{ + $output .= "$chan_in"; + $flag = 1; + } + } + }else{ + $chan_in = $ss7_array[$i]+1; + if ($chan_in < $T1CHANS){ + $chan_de = $T1CHANS; + if ($flag != 0){ + $output .= ".$chan_in-$chan_de"; + }else{ + $output .= "$chan_in-$chan_de"; + $flag = 1; + } + }else{ + if ($flag != 0){ + $output .= ".$T1CHANS"; + }else{ + $output .= "$T1CHANS"; + $flag = 1; + } + } + } + +Incrementing: + $i++; + } + return $output; +} + +sub prompt_user_ss7_chans{ + my @ss7_string = @_; + my $def_ss7_group_chan = ''; + + my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + +CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ + print("ERROR: Invalid channel number, input an integer only.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); +} + if ($line_media eq 'T1'){ + while ($ss7_group_chan>24 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 24 channels in T1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +}elsif ($line_media eq 'E1'){ + while ($ss7_group_chan>31 || $ss7_group_chan<1){ + print("Invalid channel number, there are only 31 channels in E1.\n\n"); + $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); + goto CHECK1; +} +} + return $ss7_group_chan; +} + + + + + + +sub config_t1e1{ + if (!$first_cfg) { + system('clear'); + } + print "---------------------------------------------\n"; + print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; + print "---------------------------------------------\n"; + + foreach my $dev (@hwprobe) { + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + + if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ + #do not count analog devices + $num_digital_devices_total++; + } + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + + my $hwec=0; + if ( $dev =~ /HWEC=(\d+)/){ + if($1 gt 0){ + $hwec=1; + } + } + if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + if ($hwec==0){ + $card->hwec_mode('NO'); + }else{ + $card->hwec_mode('YES'); + } + my $port=$6; + if ($6 eq 'PRI') { + $port=$5; + } + + if ( $card->card_model eq '101' | + $card->card_model eq '102' | + $card->card_model eq '104' | + $card->card_model eq '108' ){ + if (!$first_cfg) { + system('clear'); + } + if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ + print "A$1 detected on slot:$3 bus:$4\n"; + $device_has_normal_clock=$FALSE; + @device_normal_clocks = ("0"); + } + # if (!$first_cfg) { + # system('clear'); + # } + $first_cfg=0; + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; + print "$msg"; + print "-----------------------------------------------------------\n"; + my $fe_media = ''; + if ($silent==$TRUE){ + if($#silent_femedias >= 0){ + $silent_femedia=pop(@silent_femedias); + } + + $fe_media = $silent_femedia; + } else { + printf ("\nSelect media type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + my @options = ("T1", "E1", "Unused","Exit"); + $fe_media = prompt_user_list( @options, $def_femedia); + } + + if ( $fe_media eq 'Exit'){ + print "Exit without applying changes?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + print "No changes made to your configuration files.\n\n"; + exit 0; + } + }elsif ( $fe_media eq 'Unused'){ + $def_femedia=$fe_media; + my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; + print "$msg"; + prompt_user("Press any key to continue"); + }else{ + if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ + $device_has_hwec=$TRUE; + } + + $def_femedia=$fe_media; + $cfg_string.="wanpipe$devnum "; + my $a10x; + + if ($1 !~ m/104/ && $2 !~ m/SH/) { + $a10x = eval {new A10u(); } or die ($@); + $a10x->card($card); + if ($5 eq "A") { + $a10x->fe_line("1"); + } else { + $a10x->fe_line("2"); + } + } else { + $a10x = eval {new A10x(); } or die ($@); + if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ + my $abc=0; + } + $a10x->card($card); + $a10x->fe_line($6); + } + + $card->first_chan($current_zap_channel); + $a10x->fe_media($fe_media); + if ( $fe_media eq 'T1' ){ + $max_chans = 24; + $line_media = 'T1'; + + #$def_te_sig_mode=''; + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } + + + if ($silent==$FALSE){ + printf ("Configuring port %s on AFT-A%s as: %s, coding:%s, framing:%s.\n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe, + $port); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("B8ZS", "AMI"); + $def_felcode= &prompt_user_lit(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("ESF", "D4"); + $def_feframe= &prompt_user_list(@options, $def_feframe); + } + + + } else { + if($#silent_felcodes >= 0){ + $silent_felcode=pop(@silent_felcodes); + } + $def_felcode=$silent_felcode; + + if($#silent_feframes >= 0){ + $silent_feframe=pop(@silent_feframes); + } + $def_feframe=$silent_feframe; + } + + + }else{ #fe_media = E1 + $max_chans = 31; + $line_media = 'E1'; + + + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } + + if ($silent==$FALSE){ + printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", + $port, + $card->card_model, + $fe_media, + $def_felcode, + $def_feframe); + my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/){ + printf("Select line coding for port %s on %s\n", $port, $card->card_model); + my @options = ("HDB3", "AMI"); + $def_felcode= &prompt_user_list(@options, $def_felcode); + + + printf("Select framing for port %s on %s\n", $port, $card->card_model); + my @options = ("CRC4", "NCRC4","UNFRAMED"); + $def_feframe = &prompt_user_list(@options, $def_feframe); + +# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); +# my @options = ("CCS - Clear channel signalling ", "CAS"); +# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); + + } + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode on AFT-A%s port %s\n",$card->card_model, $port); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + } else { + $def_te_sig_mode="CAS"; + } + + + } else { + if($#silent_felcodes >= 0){ + $silent_felcode=pop(@silent_felcodes); + } + $def_felcode=$silent_felcode; + + if($#silent_feframes >= 0){ + $silent_feframe=pop(@silent_feframes); + } + $def_feframe=$silent_feframe; + } + + + } + $a10x->fe_lcode($def_felcode); + $a10x->fe_frame($def_feframe); + if($silent==$FALSE){ + my @options = ("NORMAL", "MASTER"); + printf ("Select clock for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_feclock=&prompt_user_list(@options, $def_feclock); + } else { + if($#silent_feclocks >= 0){ + $silent_feclock=pop(@silent_feclocks); + } + $def_feclock=$silent_feclock; + } + + $a10x->fe_clock($def_feclock); + if ( $def_feclock eq 'NORMAL') { + $device_has_normal_clock=$TRUE; + push(@device_normal_clocks, $a10x->fe_line); + } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ + printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", + $card->card_model, + $port, + $card->pci_slot, + $card->pci_bus); + printf(" Free run: Use internal oscillator on card [default] \n"); + printf(" Port N: Sync with clock from port N \n\n"); + + printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); + $a10x->te_ref_clock($def_te_ref_clock); + } + + + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + } + + + + my @options=""; + if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_smg==$TRUE && $zaptel_installed==$FALSE){ + @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); + } elsif ($is_tdm_api==$TRUE){ + $def_signalling="TDM API"; + } else { + @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); + } + if ($silent==$FALSE){ + if( $is_tdm_api == $FALSE){ + printf ("Select signalling type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); + $def_signalling=&prompt_user_list(@options,$def_signalling); + } + } else { + if($#silent_signallings >= 0){ + $silent_signalling=pop(@silent_signallings); + } + $def_signalling=$silent_signalling; + } + $a10x->signalling($def_signalling); + + if ($def_signalling eq 'TDM API'){ + printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); + my @options=("CCS","CAS"); + $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); + } elsif ($def_signalling eq 'PRI CPE' | + $def_signalling eq 'PRI NET' | + $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| + $def_signalling eq 'No Signaling (Voice Only)'){ + + $def_te_sig_mode="CCS"; + + } else { + $def_te_sig_mode="CAS"; + } + $a10x->te_sig_mode($def_te_sig_mode); + + my $ss7_chan; + my $ss7_group_start; + my $ss7_group_end; + my @ss7_chan_array; + my @ss7_sorted; + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_option(1); + print("Choose an option below to configure SS7 signalling channels:\n"); + my @options =("Configure individual signalling channels(e.g #1,#10)", + "Configure consecutive signalling channels(e.g #1-#16)"); + my $res = &prompt_user_list(@options, ""); + if ( $res eq 'Configure individual signalling channels(e.g #1,#10)'){ + goto SS7CHAN; + while (1){ + print("\nAny other SS7 signalling channel to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7CHAN: + $ss7_chan = prompt_user_ss7_chans('Specify the channel for SS7 signalling(24 for T1? 16 for E1?)'); + push(@ss7_chan_array, $ss7_chan); + $ss7_array_length = @ss7_chan_array; + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + }else{ + goto SS7GROUP; + while(1){ + print("\nAny other SS7 consecutive signalling channels to configure?\n"); + if (&prompt_user_list("YES","NO","") eq 'NO'){ + goto ENDSS7CONFIG; + }else{ +SS7GROUP: + $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); + $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); + if ($ss7_group_start > $ss7_group_end){ + print("The starting channel number is bigger than the ending one!\n"); + goto SS7GROUP; + } + my $i = 0; + for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ + push(@ss7_chan_array, $i); + my @remove_duplicate; + @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); + $ss7_array_length = @ss7_chan_array; + + if ($ss7_array_length > $max_chans){ + print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); + + @ss7_chan_array = (); + goto SS7GROUP; + } + } + if ($ss7_array_length == $max_chans){ + goto ENDSS7CONFIG; + } + } + } + } + +ENDSS7CONFIG: + + @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; + + print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); + my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); + $ss7_tdmvoicechans = $ss7_voicechans; + + if ($ss7_voicechans =~ m/(\d+)/){ + $a10x->ss7_tdminterface($1); + } + + $a10x->ss7_tdmchan($ss7_voicechans); + + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + + #wanrouter start/stop for signalling span is controlled by ss7boxd + #$startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ + $a10x->ss7_option(2); + $num_ss7_config++; + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + + }elsif ($a10x->signalling eq 'TDM API'){ + if ($a10x->te_sig_mode eq "CAS"){ + $a10x->hw_dchan('0'); + } else { + $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); + } + $card->tdmv_span_no($current_tdmapi_span); + $startup_string.="wanpipe$devnum "; + $current_tdmapi_span++; + }else{ + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $startup_string.="wanpipe$devnum "; + $current_zap_span++; + $current_zap_channel+=$max_chans; + } + + + + if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ + if ($silent==$FALSE && $config_zapata==$TRUE){ + printf ("Select switchtype for AFT-A%s on port %s \n", $card->card_model, $port); + $a10x->pri_switchtype(get_pri_switchtype()); + } else { + if($#silent_pri_switchtypes >= 0){ + $silent_priswitchtype=pop(@silent_pri_switchtypes); + } + $def_feframe=$silent_feframe; + $a10x->pri_switchtype($silent_pri_switchtype); + } + } + + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_subinterface(1); + $a10x->gen_wanpipe_ss7_subinterfaces(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(2); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + my $ss7_element; + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + + $a10x->gen_wanpipe_conf(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + }else{ + $a10x->gen_wanpipe_conf(); + } + + if ($is_smg==$TRUE && $config_zapata==$FALSE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' + | $a10x->signalling eq 'No Signaling (Voice Only)')){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ + + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + } + }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + }elsif ($is_tdm_api == $FALSE){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + $devnum++; + $num_digital_devices++; + my $msg ="\n\nPort ".$port." on A".$card->card_model." configuration complete...\n"; + print "$msg"; + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + } + + + } + + } + } + if($num_digital_devices_total!=0){ + print("\nT1/E1 card configuration complete.\n"); + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + $first_cfg=0; + } +# close SCR; +} + + +#------------------------------ANALOG FUNCTIONS------------------------------------# + + +sub config_analog{ + if($is_tdm_api==$TRUE){ + return; + } + my $a20x; + if (!$first_cfg) { + system('clear'); + } + $first_cfg=0; + print "------------------------------------\n"; + print "Configuring analog cards [A200/A400]\n"; + print "------------------------------------\n"; + + my $skip_card=$FALSE; + $zaptel_conf.="\n"; + $zapata_conf.="\n"; + foreach my $dev (@hwprobe) { + if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ + $skip_card=$FALSE; + my $card = eval {new Card(); } or die ($@); + $card->current_dir($current_dir); + $card->cfg_dir($cfg_dir); + $card->device_no($devnum); + $card->card_model($1); + $card->pci_slot($3); + $card->pci_bus($4); + $card->fe_cpu($5); + my $hwec=$7; + if ($hwec==0){ + $card->hwec_mode('NO'); + } + else{ + $card->hwec_mode('YES'); + } + if ($card->card_model eq '200' | $card->card_model eq '400'){ + $num_analog_devices_total++; + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + if($is_trixbox==$FALSE){ + if ($silent==$FALSE){ + print "\nWould you like to configure AFT-A$1 on slot:$3 bus:$4\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $skip_card=$TRUE; + } + } + } + if ($skip_card==$FALSE){ + + $a20x = eval {new A20x(); } or die ($@); + $a20x->card($card); + $card->first_chan($current_zap_channel); + + if ( $device_has_hwec==$TRUE){ + print "Will this AFT-A$1 synchronize with an existing Sangoma T1/E1 card?\n"; + print "\n WARNING: for hardware and firmware requirements, check:\n"; + print " http://wiki.sangoma.com/t1e1analogfaxing\n"; + + if (&prompt_user_list(("NO","YES","")) eq 'NO'){ + $a20x->rm_network_sync('NO'); + } else { + $a20x->rm_network_sync('YES'); + } + } + + if ($silent==$FALSE){ + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf(&prompt_hw_dtmf()); + } else { + $card->hw_dtmf("NO"); + } + $a20x->tdm_law(&prompt_tdm_law()); + } else { + if ($card->hwec_mode eq "YES"){ + $card->hw_dtmf("YES"); + } else { + $card->hw_dtmf("NO"); + } + + if($#silent_tdm_laws >= 0){ + $silent_tdm_law=pop(@silent_tdm_laws); + } + + $a20x->tdm_law($silent_tdm_law); + } + + + print "A$1 configured on slot:$3 bus:$4 span:$current_zap_span\n"; + $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; + $startup_string.="wanpipe$devnum "; + $cfg_string.="wanpipe$devnum "; + + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } + + $current_zap_channel+=24; + my $i; + $devnum++; + $num_analog_devices++; + $num_zaptel_config++; + $card->tdmv_span_no($current_zap_span); + $current_zap_span++; + $a20x->gen_wanpipe_conf(); + + }else{ + print "A$1 on slot:$3 bus:$4 not configured\n"; + prompt_user("Press any key to continue"); + } + } + }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-internal"); + $a20x->card->zap_group("1"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); + }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ + my $zap_pos = $1+$current_zap_channel-25; + $a20x->card->zap_context("from-zaptel"); + $a20x->card->zap_group("0"); + $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); + $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); + } + } + if($num_analog_devices_total!=0){ + print("\nAnalog card configuration complete\n\n"); + if( $silent==$FALSE){ + prompt_user("Press any key to continue"); + } + } + +} + diff --git a/util/wanconfig/Makefile b/util/wanconfig/Makefile index b2f8102..7cabe5f 100644 --- a/util/wanconfig/Makefile +++ b/util/wanconfig/Makefile @@ -17,7 +17,7 @@ endif WAN_VIRTUAL= # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -I$(SYSINC) -D_DEBUG_=$(DEBUG) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -I$(SYSINC) -I../../patches/kdrivers/include -D_DEBUG_=$(DEBUG) CFLAGS += -DWAN_HWEC diff --git a/util/wanconfig/diff b/util/wanconfig/diff deleted file mode 100644 index 6fc3260..0000000 --- a/util/wanconfig/diff +++ /dev/null @@ -1,139 +0,0 @@ ---- wanconfig.c 2007-04-13 19:12:32.000000000 -0400 -+++ /common/wantools/wanconfig/wanconfig.c 2007-04-18 14:57:19.000000000 -0400 -@@ -257,7 +257,7 @@ - - int show_status(void); - int show_config(void); --int show_hwprobe(void); -+int show_hwprobe(int); - int debugging(void); - int debug_read(void); - -@@ -298,6 +298,7 @@ - void free_device_link(char *devname); - int device_syncup(char *devname); - void sig_func (int sigio); -+int start_chan (int dev, link_def_t *def); - int start_link (void); - int stop_link(void); - int exec_command(unsigned char *rx_data); -@@ -470,6 +471,7 @@ - DO_SHOW_STATUS, - DO_SHOW_CONFIG, - DO_SHOW_HWPROBE, -+ DO_SHOW_HWPROBE_VERBOSE, - DO_DEBUGGING, - DO_DEBUG_READ, - } action; /* what to do */ -@@ -573,6 +575,8 @@ - { "TDMV_OPERMODE", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, opermode_name), DTYPE_STR }, - { "RM_BATTTHRESH", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, battthresh), DTYPE_UINT }, - { "RM_BATTDEBOUNCE", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, battdebounce), DTYPE_UINT }, -+ { "RM_EXTERNAL_SYNC", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, external_sync), DTYPE_UINT }, -+ - - /* TDMV parameters */ - { "TDMV_SPAN", offsetof(wandev_conf_t, tdmv_conf)+smemof(wan_tdmv_conf_t, span_no), DTYPE_UINT}, -@@ -586,7 +590,7 @@ - { "MTU", smemof(wandev_conf_t, mtu), DTYPE_UINT }, - { "UDPPORT", smemof(wandev_conf_t, udp_port), DTYPE_UINT }, - { "TTL", smemof(wandev_conf_t, ttl), DTYPE_UCHAR }, -- { "INTERFACE", smemof(wandev_conf_t, interface), DTYPE_UCHAR }, -+ { "INTERFACE", smemof(wandev_conf_t, electrical_interface), DTYPE_UCHAR }, - { "CLOCKING", smemof(wandev_conf_t, clocking), DTYPE_UCHAR }, - { "LINECODING", smemof(wandev_conf_t, line_coding), DTYPE_UCHAR }, - { "CONNECTION", smemof(wandev_conf_t, connection), DTYPE_UCHAR }, -@@ -1212,7 +1216,6 @@ - { WANCONFIG_AFT_TE1, xilinx_conftab }, - { WANCONFIG_AFT_ANALOG, xilinx_conftab }, - { WANCONFIG_AFT_TE3, xilinx_conftab }, -- { WANCONFIG_AFT_56K, xilinx_conftab }, - { WANCONFIG_BITSTRM, bitstrm_conftab }, - { WANCONFIG_SDLC, sdlc_conftab }, - { 0, NULL } -@@ -1228,7 +1231,6 @@ - { WANCONFIG_AFT_TE1, xilinx_if_conftab }, - { WANCONFIG_AFT_TE3, xilinx_if_conftab }, - { WANCONFIG_AFT_ANALOG, xilinx_if_conftab }, -- { WANCONFIG_AFT_56K, xilinx_if_conftab }, - { WANCONFIG_ASYHDLC, chdlc_conftab }, - { 0, NULL } - }; -@@ -1278,7 +1280,6 @@ - { WANCONFIG_AFT_TE1, "WAN_AFT_TE1" }, - { WANCONFIG_AFT_ANALOG, "WAN_AFT_ANALOG" }, - { WANCONFIG_AFT_TE3, "WAN_AFT_TE3" }, -- { WANCONFIG_AFT_56K, "WAN_AFT_56K" }, - { WANCONFIG_AFT, "WAN_XILINX" }, - { WANCONFIG_MFR, "WAN_MFR" }, - { WANCONFIG_DEBUG, "WAN_DEBUG" }, -@@ -1722,9 +1723,14 @@ - } - - else if( strcmp( argv[optind], "hwprobe" ) == 0 ) { -- set_action(DO_SHOW_HWPROBE); -+ if ((optind + 1 < argc) && (strcmp( argv[optind+1], "verbose" ) == 0 )){ -+ set_action(DO_SHOW_HWPROBE_VERBOSE); -+ optind++; -+ }else{ -+ set_action(DO_SHOW_HWPROBE); -+ } - } -- -+ - else if( strcmp( argv[optind], "help" ) == 0 ) { - show_help(); - } -@@ -1799,7 +1805,8 @@ - break; - - case DO_SHOW_HWPROBE: -- return show_hwprobe(); -+ case DO_SHOW_HWPROBE_VERBOSE: -+ return show_hwprobe(action); - break; - - case DO_DEBUGGING: -@@ -4663,7 +4670,7 @@ - return err; - } - --int show_hwprobe(void) -+int show_hwprobe(int action) - { - int err = 0; - -@@ -4680,7 +4687,8 @@ - memset(&procfs, 0, sizeof(wan_procfs_t)); - procfs.magic = ROUTER_MAGIC; - procfs.max_len = 2048; -- procfs.cmd = WANPIPE_PROCFS_HWPROBE; -+ procfs.cmd = (action == DO_SHOW_HWPROBE) ? -+ WANPIPE_PROCFS_HWPROBE : WANPIPE_PROCFS_HWPROBE_VERBOSE ; - procfs.data = malloc(2048); - if (procfs.data == NULL){ - show_error(ERR_SYSTEM); -@@ -4971,6 +4979,7 @@ - - #if defined(WAN_HWEC) - -+ - #define WAN_EC_PID "/etc/wanpipe/wan_ec/wan_ec_pid" - #define WAN_EC_DIR "/etc/wanpipe/wan_ec" - -@@ -4978,6 +4987,7 @@ - { - int status; - char cmd[100]; -+#if defined(__LINUX__) - DIR *dir; - - dir = opendir(WAN_EC_DIR); -@@ -4987,6 +4997,7 @@ - } - - closedir(dir); -+#endif - - /*HW_EC*/ - sprintf(cmd, "wan_ec_client %s config", devname); diff --git a/util/wanconfig/file b/util/wanconfig/file new file mode 100644 index 0000000..2fa97f9 --- /dev/null +++ b/util/wanconfig/file @@ -0,0 +1,1697 @@ +wanconfig.c:87:36: error: linux/wanpipe_version.h: No such file or directory +wanconfig.c:88:36: error: linux/wanpipe_defines.h: No such file or directory +wanconfig.c:89:32: error: linux/wanpipe_cfg.h: No such file or directory +wanconfig.c:90:28: error: linux/wanpipe.h: No such file or directory +wanconfig.c:183: error: ‘WAN_IFNAME_SZ’ undeclared here (not in a function) +wanconfig.c:194: error: expected specifier-qualifier-list before ‘wanif_conf_t’ +wanconfig.c:201: error: ‘WAN_DRVNAME_SZ’ undeclared here (not in a function) +wanconfig.c:208: error: expected specifier-qualifier-list before ‘wandev_conf_t’ +wanconfig.c:284: error: expected ‘)’ before ‘*’ token +wanconfig.c:285: error: expected ‘)’ before ‘*’ token +wanconfig.c:492: error: expected specifier-qualifier-list before ‘wandev_conf_t’ +wanconfig.c:522: error: expected specifier-qualifier-list before ‘wandev_conf_t’ +wanconfig.c:522: error: expected ‘}’ before ‘)’ token +wanconfig.c:522: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:522: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:523: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:524: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:525: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:526: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:527: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:528: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:529: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:530: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:531: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:532: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:540: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:541: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:542: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:543: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:544: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:545: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:548: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:549: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:550: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:552: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:553: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:554: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:555: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:556: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:557: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:558: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:560: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:561: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:562: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:564: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:565: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:566: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:567: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:568: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:569: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:570: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:571: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:572: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:573: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:574: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:575: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:576: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:579: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:580: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:581: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:583: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:584: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:586: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:588: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:589: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:590: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:591: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:592: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:593: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:594: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:595: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:596: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:597: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:598: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:599: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:600: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:601: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:602: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:603: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:604: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:605: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:606: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:607: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:608: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:609: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:611: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:612: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:628: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:632: error: expected specifier-qualifier-list before ‘wan_ppp_conf_t’ +wanconfig.c:632: error: initializer element is not constant +wanconfig.c:632: error: (near initialization for ‘ppp_conftab[0].offset’) +wanconfig.c:632: error: expected ‘}’ before ‘)’ token +wanconfig.c:632: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:632: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:633: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:634: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:636: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:637: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:638: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:639: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:640: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:641: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:642: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:643: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:645: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:652: error: expected specifier-qualifier-list before ‘wan_chdlc_conf_t’ +wanconfig.c:652: error: initializer element is not constant +wanconfig.c:652: error: (near initialization for ‘chdlc_conftab[0].offset’) +wanconfig.c:652: error: expected ‘}’ before ‘)’ token +wanconfig.c:652: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:652: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:653: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:654: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:655: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:656: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:657: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:658: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:659: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:660: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:661: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:663: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:668: error: expected specifier-qualifier-list before ‘wan_sppp_if_conf_t’ +wanconfig.c:668: error: initializer element is not constant +wanconfig.c:668: error: (near initialization for ‘sppp_conftab[0].offset’) +wanconfig.c:668: error: expected ‘}’ before ‘)’ token +wanconfig.c:668: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:668: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:670: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:671: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:672: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:674: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:675: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:676: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:678: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:679: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:683: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:686: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:690: error: expected specifier-qualifier-list before ‘wan_fr_conf_t’ +wanconfig.c:690: error: initializer element is not constant +wanconfig.c:690: error: (near initialization for ‘fr_conftab[0].offset’) +wanconfig.c:690: error: expected ‘}’ before ‘)’ token +wanconfig.c:690: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:690: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:691: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:692: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:693: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:694: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:695: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:696: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:697: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:698: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:699: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:700: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:702: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:706: error: expected specifier-qualifier-list before ‘wan_xilinx_conf_t’ +wanconfig.c:706: error: initializer element is not constant +wanconfig.c:706: error: (near initialization for ‘xilinx_conftab[0].offset’) +wanconfig.c:706: error: expected ‘}’ before ‘)’ token +wanconfig.c:706: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:706: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:707: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:708: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:709: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:712: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:714: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:719: error: expected specifier-qualifier-list before ‘wan_bitstrm_conf_t’ +wanconfig.c:719: error: initializer element is not constant +wanconfig.c:719: error: (near initialization for ‘bitstrm_conftab[0].offset’) +wanconfig.c:719: error: expected ‘}’ before ‘)’ token +wanconfig.c:719: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:719: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:720: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:721: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:722: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:723: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:724: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:725: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:727: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:731: error: expected specifier-qualifier-list before ‘wan_sdlc_conf_t’ +wanconfig.c:731: error: initializer element is not constant +wanconfig.c:731: error: (near initialization for ‘sdlc_conftab[0].offset’) +wanconfig.c:731: error: expected ‘}’ before ‘)’ token +wanconfig.c:731: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:731: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:732: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:733: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:734: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:736: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:737: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:738: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:739: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:740: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:742: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:743: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:744: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:745: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:746: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:747: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:749: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:752: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:757: error: expected specifier-qualifier-list before ‘wan_xdlc_conf_t’ +wanconfig.c:757: error: initializer element is not constant +wanconfig.c:757: error: (near initialization for ‘xdlc_conftab[0].offset’) +wanconfig.c:757: error: expected ‘}’ before ‘)’ token +wanconfig.c:757: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:757: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:758: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:760: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:761: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:762: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:764: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:766: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:767: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:768: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:770: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:771: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:772: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:774: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:777: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:810: error: expected specifier-qualifier-list before ‘wan_atm_conf_t’ +wanconfig.c:810: error: initializer element is not constant +wanconfig.c:810: error: (near initialization for ‘atm_conftab[0].offset’) +wanconfig.c:810: error: expected ‘}’ before ‘)’ token +wanconfig.c:810: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:810: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:811: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:812: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:813: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:814: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:815: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:816: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:817: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:819: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:826: error: expected specifier-qualifier-list before ‘wan_atm_conf_if_t’ +wanconfig.c:826: error: initializer element is not constant +wanconfig.c:826: error: (near initialization for ‘atm_if_conftab[0].offset’) +wanconfig.c:826: error: expected ‘}’ before ‘)’ token +wanconfig.c:826: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:826: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:827: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:828: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:830: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:831: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:832: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:833: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:834: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:835: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:836: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:839: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:840: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:841: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:842: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:843: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:844: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:845: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:846: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:849: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:853: error: expected specifier-qualifier-list before ‘wan_xilinx_conf_if_t’ +wanconfig.c:853: error: initializer element is not constant +wanconfig.c:853: error: (near initialization for ‘xilinx_if_conftab[0].offset’) +wanconfig.c:853: error: expected ‘}’ before ‘)’ token +wanconfig.c:853: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:853: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:854: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:855: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:856: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:857: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:858: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:859: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:860: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:861: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:862: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:865: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:867: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:872: error: expected specifier-qualifier-list before ‘wan_bitstrm_conf_if_t’ +wanconfig.c:872: error: initializer element is not constant +wanconfig.c:872: error: (near initialization for ‘bitstrm_if_conftab[0].offset’) +wanconfig.c:872: error: expected ‘}’ before ‘)’ token +wanconfig.c:872: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:872: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:873: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:874: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:876: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:881: error: expected specifier-qualifier-list before ‘wan_adsl_conf_t’ +wanconfig.c:881: error: initializer element is not constant +wanconfig.c:881: error: (near initialization for ‘adsl_conftab[0].offset’) +wanconfig.c:881: error: expected ‘}’ before ‘)’ token +wanconfig.c:881: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:881: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:883: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:884: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:886: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:888: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:889: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:891: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:893: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:894: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:896: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:898: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:900: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:901: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:903: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:904: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:905: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:906: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:907: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:908: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:909: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:910: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:911: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:912: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:913: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:914: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:915: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:916: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:919: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:920: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:921: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:922: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:923: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:924: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:925: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:926: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:927: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:928: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:929: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:930: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:931: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:932: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:934: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:935: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:937: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:941: error: expected specifier-qualifier-list before ‘wan_bscstrm_conf_t’ +wanconfig.c:941: error: initializer element is not constant +wanconfig.c:941: error: (near initialization for ‘bscstrm_conftab[0].offset’) +wanconfig.c:941: error: expected ‘}’ before ‘)’ token +wanconfig.c:941: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:941: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:942: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:943: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:944: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:945: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:946: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:947: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:948: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:949: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:950: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:951: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:953: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:958: error: expected specifier-qualifier-list before ‘wan_ss7_conf_t’ +wanconfig.c:958: error: initializer element is not constant +wanconfig.c:958: error: (near initialization for ‘ss7_conftab[0].offset’) +wanconfig.c:958: error: expected ‘}’ before ‘)’ token +wanconfig.c:958: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:958: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:959: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:960: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:961: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:962: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:963: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:964: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:965: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:966: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:967: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:968: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:969: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:970: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:971: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:972: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:973: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:974: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:975: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:976: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:977: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:978: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:979: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:980: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:981: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:982: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:983: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:984: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:985: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:986: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:987: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:989: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:995: error: expected specifier-qualifier-list before ‘wan_x25_conf_t’ +wanconfig.c:995: error: initializer element is not constant +wanconfig.c:995: error: (near initialization for ‘x25_conftab[0].offset’) +wanconfig.c:995: error: expected ‘}’ before ‘)’ token +wanconfig.c:995: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:995: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:996: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:997: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:998: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:999: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1000: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1001: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1002: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1003: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1004: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1005: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1006: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1007: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1008: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1009: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1010: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1011: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1012: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1013: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1014: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1015: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1016: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1017: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1018: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1019: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1020: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1021: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1022: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1024: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:1029: error: expected specifier-qualifier-list before ‘wan_lapb_if_conf_t’ +wanconfig.c:1029: error: initializer element is not constant +wanconfig.c:1029: error: (near initialization for ‘lapb_annexg_conftab[0].offset’) +wanconfig.c:1029: error: expected ‘}’ before ‘)’ token +wanconfig.c:1029: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:1029: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1030: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1031: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1032: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1033: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1034: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1035: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1036: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1037: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1038: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1039: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1040: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1042: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1043: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1044: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1046: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1049: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:1054: error: expected specifier-qualifier-list before ‘wan_x25_if_conf_t’ +wanconfig.c:1054: error: initializer element is not constant +wanconfig.c:1054: error: (near initialization for ‘x25_annexg_conftab[0].offset’) +wanconfig.c:1054: error: expected ‘}’ before ‘)’ token +wanconfig.c:1054: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:1054: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1055: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1056: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1057: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1058: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1059: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1060: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1061: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1062: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1063: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1064: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1066: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1067: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1068: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1069: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1071: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1072: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1073: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1074: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1076: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1077: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1079: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1080: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1082: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1083: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1085: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1086: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1087: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1089: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1090: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1091: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1092: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1093: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1095: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1096: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1097: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1100: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:1105: error: expected specifier-qualifier-list before ‘wan_dsp_if_conf_t’ +wanconfig.c:1105: error: initializer element is not constant +wanconfig.c:1105: error: (near initialization for ‘dsp_annexg_conftab[0].offset’) +wanconfig.c:1105: error: expected ‘}’ before ‘)’ token +wanconfig.c:1105: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:1105: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1106: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1107: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1108: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1109: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1110: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1111: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1112: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1114: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:1118: error: expected specifier-qualifier-list before ‘wanif_conf_t’ +wanconfig.c:1118: error: initializer element is not constant +wanconfig.c:1118: error: (near initialization for ‘chan_conftab[0].offset’) +wanconfig.c:1118: error: expected ‘}’ before ‘)’ token +wanconfig.c:1118: error: expected ‘,’ or ‘;’ before ‘)’ token +wanconfig.c:1118: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1119: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1120: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1121: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1122: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1123: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1124: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1125: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1126: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1127: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1128: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1129: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1130: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1131: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1132: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1133: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1134: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1135: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1136: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1137: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1138: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1139: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1140: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1141: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1143: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1144: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1145: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1146: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1148: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1154: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1155: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1156: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1157: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1160: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1161: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1162: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1163: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1164: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1165: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1166: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1167: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1168: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1169: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1170: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1171: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1172: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1173: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1174: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1175: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1176: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1177: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1178: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1179: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1181: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1183: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1184: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1186: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1187: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1188: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1192: error: expected identifier or ‘(’ before ‘,’ token +wanconfig.c:1195: error: expected identifier or ‘(’ before ‘}’ token +wanconfig.c:1199: error: ‘WANCONFIG_PPP’ undeclared here (not in a function) +wanconfig.c:1199: error: initializer element is not constant +wanconfig.c:1199: error: (near initialization for ‘conf_def_tables[0].val’) +wanconfig.c:1200: error: ‘WANCONFIG_FR’ undeclared here (not in a function) +wanconfig.c:1200: error: initializer element is not constant +wanconfig.c:1200: error: (near initialization for ‘conf_def_tables[1].val’) +wanconfig.c:1201: error: ‘WANCONFIG_X25’ undeclared here (not in a function) +wanconfig.c:1201: error: initializer element is not constant +wanconfig.c:1201: error: (near initialization for ‘conf_def_tables[2].val’) +wanconfig.c:1202: error: ‘WANCONFIG_ADCCP’ undeclared here (not in a function) +wanconfig.c:1202: error: initializer element is not constant +wanconfig.c:1202: error: (near initialization for ‘conf_def_tables[3].val’) +wanconfig.c:1203: error: ‘WANCONFIG_CHDLC’ undeclared here (not in a function) +wanconfig.c:1203: error: initializer element is not constant +wanconfig.c:1203: error: (near initialization for ‘conf_def_tables[4].val’) +wanconfig.c:1204: error: ‘WANCONFIG_ASYHDLC’ undeclared here (not in a function) +wanconfig.c:1204: error: initializer element is not constant +wanconfig.c:1204: error: (near initialization for ‘conf_def_tables[5].val’) +wanconfig.c:1205: error: ‘WANCONFIG_MPPP’ undeclared here (not in a function) +wanconfig.c:1205: error: initializer element is not constant +wanconfig.c:1205: error: (near initialization for ‘conf_def_tables[6].val’) +wanconfig.c:1206: error: ‘WANCONFIG_LIP_ATM’ undeclared here (not in a function) +wanconfig.c:1206: error: initializer element is not constant +wanconfig.c:1206: error: (near initialization for ‘conf_def_tables[7].val’) +wanconfig.c:1207: error: ‘WANCONFIG_LIP_KATM’ undeclared here (not in a function) +wanconfig.c:1207: error: initializer element is not constant +wanconfig.c:1207: error: (near initialization for ‘conf_def_tables[8].val’) +wanconfig.c:1208: error: ‘WANCONFIG_MFR’ undeclared here (not in a function) +wanconfig.c:1208: error: initializer element is not constant +wanconfig.c:1208: error: (near initialization for ‘conf_def_tables[9].val’) +wanconfig.c:1209: error: ‘WANCONFIG_SS7’ undeclared here (not in a function) +wanconfig.c:1209: error: initializer element is not constant +wanconfig.c:1209: error: (near initialization for ‘conf_def_tables[10].val’) +wanconfig.c:1210: error: ‘WANCONFIG_ADSL’ undeclared here (not in a function) +wanconfig.c:1210: error: initializer element is not constant +wanconfig.c:1210: error: (near initialization for ‘conf_def_tables[11].val’) +wanconfig.c:1211: error: ‘WANCONFIG_BSCSTRM’ undeclared here (not in a function) +wanconfig.c:1211: error: initializer element is not constant +wanconfig.c:1211: error: (near initialization for ‘conf_def_tables[12].val’) +wanconfig.c:1212: error: ‘WANCONFIG_ATM’ undeclared here (not in a function) +wanconfig.c:1212: error: initializer element is not constant +wanconfig.c:1212: error: (near initialization for ‘conf_def_tables[13].val’) +wanconfig.c:1213: error: ‘WANCONFIG_MLINK_PPP’ undeclared here (not in a function) +wanconfig.c:1213: error: initializer element is not constant +wanconfig.c:1213: error: (near initialization for ‘conf_def_tables[14].val’) +wanconfig.c:1214: error: ‘WANCONFIG_AFT’ undeclared here (not in a function) +wanconfig.c:1214: error: initializer element is not constant +wanconfig.c:1214: error: (near initialization for ‘conf_def_tables[15].val’) +wanconfig.c:1215: error: ‘WANCONFIG_AFT_TE1’ undeclared here (not in a function) +wanconfig.c:1215: error: initializer element is not constant +wanconfig.c:1215: error: (near initialization for ‘conf_def_tables[16].val’) +wanconfig.c:1216: error: ‘WANCONFIG_AFT_ANALOG’ undeclared here (not in a function) +wanconfig.c:1216: error: initializer element is not constant +wanconfig.c:1216: error: (near initialization for ‘conf_def_tables[17].val’) +wanconfig.c:1217: error: ‘WANCONFIG_AFT_TE3’ undeclared here (not in a function) +wanconfig.c:1217: error: initializer element is not constant +wanconfig.c:1217: error: (near initialization for ‘conf_def_tables[18].val’) +wanconfig.c:1218: error: ‘WANCONFIG_AFT_56K’ undeclared here (not in a function) +wanconfig.c:1218: error: initializer element is not constant +wanconfig.c:1218: error: (near initialization for ‘conf_def_tables[19].val’) +wanconfig.c:1219: error: ‘WANCONFIG_BITSTRM’ undeclared here (not in a function) +wanconfig.c:1219: error: initializer element is not constant +wanconfig.c:1219: error: (near initialization for ‘conf_def_tables[20].val’) +wanconfig.c:1220: error: ‘WANCONFIG_SDLC’ undeclared here (not in a function) +wanconfig.c:1220: error: initializer element is not constant +wanconfig.c:1220: error: (near initialization for ‘conf_def_tables[21].val’) +wanconfig.c:1226: error: initializer element is not constant +wanconfig.c:1226: error: (near initialization for ‘conf_if_def_tables[0].val’) +wanconfig.c:1227: error: initializer element is not constant +wanconfig.c:1227: error: (near initialization for ‘conf_if_def_tables[1].val’) +wanconfig.c:1228: error: initializer element is not constant +wanconfig.c:1228: error: (near initialization for ‘conf_if_def_tables[2].val’) +wanconfig.c:1229: error: initializer element is not constant +wanconfig.c:1229: error: (near initialization for ‘conf_if_def_tables[3].val’) +wanconfig.c:1230: error: initializer element is not constant +wanconfig.c:1230: error: (near initialization for ‘conf_if_def_tables[4].val’) +wanconfig.c:1231: error: initializer element is not constant +wanconfig.c:1231: error: (near initialization for ‘conf_if_def_tables[5].val’) +wanconfig.c:1232: error: initializer element is not constant +wanconfig.c:1232: error: (near initialization for ‘conf_if_def_tables[6].val’) +wanconfig.c:1233: error: initializer element is not constant +wanconfig.c:1233: error: (near initialization for ‘conf_if_def_tables[7].val’) +wanconfig.c:1234: error: initializer element is not constant +wanconfig.c:1234: error: (near initialization for ‘conf_if_def_tables[8].val’) +wanconfig.c:1235: error: initializer element is not constant +wanconfig.c:1235: error: (near initialization for ‘conf_if_def_tables[9].val’) +wanconfig.c:1260: error: initializer element is not constant +wanconfig.c:1260: error: (near initialization for ‘config_id_str[0].val’) +wanconfig.c:1261: error: initializer element is not constant +wanconfig.c:1261: error: (near initialization for ‘config_id_str[1].val’) +wanconfig.c:1262: error: initializer element is not constant +wanconfig.c:1262: error: (near initialization for ‘config_id_str[2].val’) +wanconfig.c:1263: error: initializer element is not constant +wanconfig.c:1263: error: (near initialization for ‘config_id_str[3].val’) +wanconfig.c:1264: error: initializer element is not constant +wanconfig.c:1264: error: (near initialization for ‘config_id_str[4].val’) +wanconfig.c:1265: error: ‘WANCONFIG_BSC’ undeclared here (not in a function) +wanconfig.c:1265: error: initializer element is not constant +wanconfig.c:1265: error: (near initialization for ‘config_id_str[5].val’) +wanconfig.c:1266: error: ‘WANCONFIG_HDLC’ undeclared here (not in a function) +wanconfig.c:1266: error: initializer element is not constant +wanconfig.c:1266: error: (near initialization for ‘config_id_str[6].val’) +wanconfig.c:1267: error: initializer element is not constant +wanconfig.c:1267: error: (near initialization for ‘config_id_str[7].val’) +wanconfig.c:1268: error: ‘WANCONFIG_MPROT’ undeclared here (not in a function) +wanconfig.c:1268: error: initializer element is not constant +wanconfig.c:1268: error: (near initialization for ‘config_id_str[8].val’) +wanconfig.c:1269: error: initializer element is not constant +wanconfig.c:1269: error: (near initialization for ‘config_id_str[9].val’) +wanconfig.c:1270: error: initializer element is not constant +wanconfig.c:1270: error: (near initialization for ‘config_id_str[10].val’) +wanconfig.c:1271: error: initializer element is not constant +wanconfig.c:1271: error: (near initialization for ‘config_id_str[11].val’) +wanconfig.c:1272: error: ‘WANCONFIG_EDUKIT’ undeclared here (not in a function) +wanconfig.c:1272: error: initializer element is not constant +wanconfig.c:1272: error: (near initialization for ‘config_id_str[12].val’) +wanconfig.c:1273: error: initializer element is not constant +wanconfig.c:1273: error: (near initialization for ‘config_id_str[13].val’) +wanconfig.c:1274: error: initializer element is not constant +wanconfig.c:1274: error: (near initialization for ‘config_id_str[14].val’) +wanconfig.c:1275: error: initializer element is not constant +wanconfig.c:1275: error: (near initialization for ‘config_id_str[15].val’) +wanconfig.c:1276: error: initializer element is not constant +wanconfig.c:1276: error: (near initialization for ‘config_id_str[16].val’) +wanconfig.c:1277: error: initializer element is not constant +wanconfig.c:1277: error: (near initialization for ‘config_id_str[17].val’) +wanconfig.c:1278: error: initializer element is not constant +wanconfig.c:1278: error: (near initialization for ‘config_id_str[18].val’) +wanconfig.c:1279: error: ‘WANCONFIG_POS’ undeclared here (not in a function) +wanconfig.c:1279: error: initializer element is not constant +wanconfig.c:1279: error: (near initialization for ‘config_id_str[19].val’) +wanconfig.c:1280: error: initializer element is not constant +wanconfig.c:1280: error: (near initialization for ‘config_id_str[20].val’) +wanconfig.c:1281: error: initializer element is not constant +wanconfig.c:1281: error: (near initialization for ‘config_id_str[21].val’) +wanconfig.c:1282: error: initializer element is not constant +wanconfig.c:1282: error: (near initialization for ‘config_id_str[22].val’) +wanconfig.c:1283: error: initializer element is not constant +wanconfig.c:1283: error: (near initialization for ‘config_id_str[23].val’) +wanconfig.c:1284: error: initializer element is not constant +wanconfig.c:1284: error: (near initialization for ‘config_id_str[24].val’) +wanconfig.c:1285: error: initializer element is not constant +wanconfig.c:1285: error: (near initialization for ‘config_id_str[25].val’) +wanconfig.c:1286: error: initializer element is not constant +wanconfig.c:1286: error: (near initialization for ‘config_id_str[26].val’) +wanconfig.c:1287: error: ‘WANCONFIG_DEBUG’ undeclared here (not in a function) +wanconfig.c:1287: error: initializer element is not constant +wanconfig.c:1287: error: (near initialization for ‘config_id_str[27].val’) +wanconfig.c:1288: error: initializer element is not constant +wanconfig.c:1288: error: (near initialization for ‘config_id_str[28].val’) +wanconfig.c:1289: error: initializer element is not constant +wanconfig.c:1289: error: (near initialization for ‘config_id_str[29].val’) +wanconfig.c:1299: error: ‘WANOPT_OFF’ undeclared here (not in a function) +wanconfig.c:1299: error: initializer element is not constant +wanconfig.c:1299: error: (near initialization for ‘sym_table[0].val’) +wanconfig.c:1300: error: ‘WANOPT_ON’ undeclared here (not in a function) +wanconfig.c:1300: error: initializer element is not constant +wanconfig.c:1300: error: (near initialization for ‘sym_table[1].val’) +wanconfig.c:1301: error: ‘WANOPT_NO’ undeclared here (not in a function) +wanconfig.c:1301: error: initializer element is not constant +wanconfig.c:1301: error: (near initialization for ‘sym_table[2].val’) +wanconfig.c:1302: error: ‘WANOPT_YES’ undeclared here (not in a function) +wanconfig.c:1302: error: initializer element is not constant +wanconfig.c:1302: error: (near initialization for ‘sym_table[3].val’) +wanconfig.c:1304: error: ‘WANOPT_RS232’ undeclared here (not in a function) +wanconfig.c:1304: error: initializer element is not constant +wanconfig.c:1304: error: (near initialization for ‘sym_table[4].val’) +wanconfig.c:1305: error: ‘WANOPT_V35’ undeclared here (not in a function) +wanconfig.c:1305: error: initializer element is not constant +wanconfig.c:1305: error: (near initialization for ‘sym_table[5].val’) +wanconfig.c:1307: error: ‘WANOPT_NRZ’ undeclared here (not in a function) +wanconfig.c:1307: error: initializer element is not constant +wanconfig.c:1307: error: (near initialization for ‘sym_table[6].val’) +wanconfig.c:1308: error: ‘WANOPT_NRZI’ undeclared here (not in a function) +wanconfig.c:1308: error: initializer element is not constant +wanconfig.c:1308: error: (near initialization for ‘sym_table[7].val’) +wanconfig.c:1309: error: ‘WANOPT_FM0’ undeclared here (not in a function) +wanconfig.c:1309: error: initializer element is not constant +wanconfig.c:1309: error: (near initialization for ‘sym_table[8].val’) +wanconfig.c:1310: error: ‘WANOPT_FM1’ undeclared here (not in a function) +wanconfig.c:1310: error: initializer element is not constant +wanconfig.c:1310: error: (near initialization for ‘sym_table[9].val’) +wanconfig.c:1313: error: ‘WANOPT_IDLE_FLAG’ undeclared here (not in a function) +wanconfig.c:1313: error: initializer element is not constant +wanconfig.c:1313: error: (near initialization for ‘sym_table[10].val’) +wanconfig.c:1314: error: ‘WANOPT_IDLE_MARK’ undeclared here (not in a function) +wanconfig.c:1314: error: initializer element is not constant +wanconfig.c:1314: error: (near initialization for ‘sym_table[11].val’) +wanconfig.c:1317: error: ‘WANOPT_POINTTOPOINT’ undeclared here (not in a function) +wanconfig.c:1317: error: initializer element is not constant +wanconfig.c:1317: error: (near initialization for ‘sym_table[12].val’) +wanconfig.c:1318: error: ‘WANOPT_MULTIDROP’ undeclared here (not in a function) +wanconfig.c:1318: error: initializer element is not constant +wanconfig.c:1318: error: (near initialization for ‘sym_table[13].val’) +wanconfig.c:1320: error: ‘WANOPT_EXTERNAL’ undeclared here (not in a function) +wanconfig.c:1320: error: initializer element is not constant +wanconfig.c:1320: error: (near initialization for ‘sym_table[14].val’) +wanconfig.c:1321: error: ‘WANOPT_INTERNAL’ undeclared here (not in a function) +wanconfig.c:1321: error: initializer element is not constant +wanconfig.c:1321: error: (near initialization for ‘sym_table[15].val’) +wanconfig.c:1323: error: ‘WANOPT_DTE’ undeclared here (not in a function) +wanconfig.c:1323: error: initializer element is not constant +wanconfig.c:1323: error: (near initialization for ‘sym_table[16].val’) +wanconfig.c:1324: error: ‘WANOPT_DCE’ undeclared here (not in a function) +wanconfig.c:1324: error: initializer element is not constant +wanconfig.c:1324: error: (near initialization for ‘sym_table[17].val’) +wanconfig.c:1325: error: ‘WANOPT_CPE’ undeclared here (not in a function) +wanconfig.c:1325: error: initializer element is not constant +wanconfig.c:1325: error: (near initialization for ‘sym_table[18].val’) +wanconfig.c:1326: error: ‘WANOPT_NODE’ undeclared here (not in a function) +wanconfig.c:1326: error: initializer element is not constant +wanconfig.c:1326: error: (near initialization for ‘sym_table[19].val’) +wanconfig.c:1327: error: ‘WANOPT_SECONDARY’ undeclared here (not in a function) +wanconfig.c:1327: error: initializer element is not constant +wanconfig.c:1327: error: (near initialization for ‘sym_table[20].val’) +wanconfig.c:1328: error: ‘WANOPT_PRIMARY’ undeclared here (not in a function) +wanconfig.c:1328: error: initializer element is not constant +wanconfig.c:1328: error: (near initialization for ‘sym_table[21].val’) +wanconfig.c:1330: error: ‘WANOPT_PERMANENT’ undeclared here (not in a function) +wanconfig.c:1330: error: initializer element is not constant +wanconfig.c:1330: error: (near initialization for ‘sym_table[22].val’) +wanconfig.c:1331: error: ‘WANOPT_SWITCHED’ undeclared here (not in a function) +wanconfig.c:1331: error: initializer element is not constant +wanconfig.c:1331: error: (near initialization for ‘sym_table[23].val’) +wanconfig.c:1332: error: ‘WANOPT_ONDEMAND’ undeclared here (not in a function) +wanconfig.c:1332: error: initializer element is not constant +wanconfig.c:1332: error: (near initialization for ‘sym_table[24].val’) +wanconfig.c:1334: error: ‘WANOPT_FR_ANSI’ undeclared here (not in a function) +wanconfig.c:1334: error: initializer element is not constant +wanconfig.c:1334: error: (near initialization for ‘sym_table[25].val’) +wanconfig.c:1335: error: ‘WANOPT_FR_Q933’ undeclared here (not in a function) +wanconfig.c:1335: error: initializer element is not constant +wanconfig.c:1335: error: (near initialization for ‘sym_table[26].val’) +wanconfig.c:1336: error: ‘WANOPT_FR_LMI’ undeclared here (not in a function) +wanconfig.c:1336: error: initializer element is not constant +wanconfig.c:1336: error: (near initialization for ‘sym_table[27].val’) +wanconfig.c:1337: error: ‘WANOPT_FR_NO_LMI’ undeclared here (not in a function) +wanconfig.c:1337: error: initializer element is not constant +wanconfig.c:1337: error: (near initialization for ‘sym_table[28].val’) +wanconfig.c:1339: error: ‘WANOPT_PPP_STATIC’ undeclared here (not in a function) +wanconfig.c:1339: error: initializer element is not constant +wanconfig.c:1339: error: (near initialization for ‘sym_table[29].val’) +wanconfig.c:1340: error: ‘WANOPT_PPP_HOST’ undeclared here (not in a function) +wanconfig.c:1340: error: initializer element is not constant +wanconfig.c:1340: error: (near initialization for ‘sym_table[30].val’) +wanconfig.c:1341: error: ‘WANOPT_PPP_PEER’ undeclared here (not in a function) +wanconfig.c:1341: error: initializer element is not constant +wanconfig.c:1341: error: (near initialization for ‘sym_table[31].val’) +wanconfig.c:1347: error: ‘WANOPT_PRI’ undeclared here (not in a function) +wanconfig.c:1347: error: initializer element is not constant +wanconfig.c:1347: error: (near initialization for ‘sym_table[32].val’) +wanconfig.c:1348: error: ‘WANOPT_SEC’ undeclared here (not in a function) +wanconfig.c:1348: error: initializer element is not constant +wanconfig.c:1348: error: (near initialization for ‘sym_table[33].val’) +wanconfig.c:1351: error: ‘WANOPT_INTR’ undeclared here (not in a function) +wanconfig.c:1351: error: initializer element is not constant +wanconfig.c:1351: error: (near initialization for ‘sym_table[34].val’) +wanconfig.c:1352: error: ‘WANOPT_POLL’ undeclared here (not in a function) +wanconfig.c:1352: error: initializer element is not constant +wanconfig.c:1352: error: (near initialization for ‘sym_table[35].val’) +wanconfig.c:1354: error: ‘WANOPT_ONE’ undeclared here (not in a function) +wanconfig.c:1354: error: initializer element is not constant +wanconfig.c:1354: error: (near initialization for ‘sym_table[36].val’) +wanconfig.c:1355: error: ‘WANOPT_TWO’ undeclared here (not in a function) +wanconfig.c:1355: error: initializer element is not constant +wanconfig.c:1355: error: (near initialization for ‘sym_table[37].val’) +wanconfig.c:1356: error: ‘WANOPT_ONE_AND_HALF’ undeclared here (not in a function) +wanconfig.c:1356: error: initializer element is not constant +wanconfig.c:1356: error: (near initialization for ‘sym_table[38].val’) +wanconfig.c:1357: error: ‘WANOPT_NONE’ undeclared here (not in a function) +wanconfig.c:1357: error: initializer element is not constant +wanconfig.c:1357: error: (near initialization for ‘sym_table[39].val’) +wanconfig.c:1358: error: ‘WANOPT_EVEN’ undeclared here (not in a function) +wanconfig.c:1358: error: initializer element is not constant +wanconfig.c:1358: error: (near initialization for ‘sym_table[40].val’) +wanconfig.c:1359: error: ‘WANOPT_ODD’ undeclared here (not in a function) +wanconfig.c:1359: error: initializer element is not constant +wanconfig.c:1359: error: (near initialization for ‘sym_table[41].val’) +wanconfig.c:1361: error: ‘WANOPT_TTY_SYNC’ undeclared here (not in a function) +wanconfig.c:1361: error: initializer element is not constant +wanconfig.c:1361: error: (near initialization for ‘sym_table[42].val’) +wanconfig.c:1362: error: ‘WANOPT_TTY_ASYNC’ undeclared here (not in a function) +wanconfig.c:1362: error: initializer element is not constant +wanconfig.c:1362: error: (near initialization for ‘sym_table[43].val’) +wanconfig.c:1365: error: ‘WANOPT_FR_EEK_REQUEST’ undeclared here (not in a function) +wanconfig.c:1365: error: initializer element is not constant +wanconfig.c:1365: error: (near initialization for ‘sym_table[44].val’) +wanconfig.c:1366: error: ‘WANOPT_FR_EEK_REPLY’ undeclared here (not in a function) +wanconfig.c:1366: error: initializer element is not constant +wanconfig.c:1366: error: (near initialization for ‘sym_table[45].val’) +wanconfig.c:1372: error: ‘WAN_MEDIA_T1’ undeclared here (not in a function) +wanconfig.c:1372: error: initializer element is not constant +wanconfig.c:1372: error: (near initialization for ‘sym_table[46].val’) +wanconfig.c:1373: error: ‘WAN_MEDIA_E1’ undeclared here (not in a function) +wanconfig.c:1373: error: initializer element is not constant +wanconfig.c:1373: error: (near initialization for ‘sym_table[47].val’) +wanconfig.c:1374: error: ‘WAN_MEDIA_J1’ undeclared here (not in a function) +wanconfig.c:1374: error: initializer element is not constant +wanconfig.c:1374: error: (near initialization for ‘sym_table[48].val’) +wanconfig.c:1375: error: ‘WAN_MEDIA_56K’ undeclared here (not in a function) +wanconfig.c:1375: error: initializer element is not constant +wanconfig.c:1375: error: (near initialization for ‘sym_table[49].val’) +wanconfig.c:1376: error: ‘WAN_MEDIA_DS3’ undeclared here (not in a function) +wanconfig.c:1376: error: initializer element is not constant +wanconfig.c:1376: error: (near initialization for ‘sym_table[50].val’) +wanconfig.c:1377: error: ‘WAN_MEDIA_STS1’ undeclared here (not in a function) +wanconfig.c:1377: error: initializer element is not constant +wanconfig.c:1377: error: (near initialization for ‘sym_table[51].val’) +wanconfig.c:1378: error: ‘WAN_MEDIA_E3’ undeclared here (not in a function) +wanconfig.c:1378: error: initializer element is not constant +wanconfig.c:1378: error: (near initialization for ‘sym_table[52].val’) +wanconfig.c:1379: error: ‘WAN_MEDIA_FXOFXS’ undeclared here (not in a function) +wanconfig.c:1379: error: initializer element is not constant +wanconfig.c:1379: error: (near initialization for ‘sym_table[53].val’) +wanconfig.c:1380: error: ‘WAN_LCODE_AMI’ undeclared here (not in a function) +wanconfig.c:1380: error: initializer element is not constant +wanconfig.c:1380: error: (near initialization for ‘sym_table[54].val’) +wanconfig.c:1381: error: ‘WAN_LCODE_B8ZS’ undeclared here (not in a function) +wanconfig.c:1381: error: initializer element is not constant +wanconfig.c:1381: error: (near initialization for ‘sym_table[55].val’) +wanconfig.c:1382: error: ‘WAN_LCODE_HDB3’ undeclared here (not in a function) +wanconfig.c:1382: error: initializer element is not constant +wanconfig.c:1382: error: (near initialization for ‘sym_table[56].val’) +wanconfig.c:1383: error: ‘WAN_LCODE_B3ZS’ undeclared here (not in a function) +wanconfig.c:1383: error: initializer element is not constant +wanconfig.c:1383: error: (near initialization for ‘sym_table[57].val’) +wanconfig.c:1384: error: ‘WAN_FR_D4’ undeclared here (not in a function) +wanconfig.c:1384: error: initializer element is not constant +wanconfig.c:1384: error: (near initialization for ‘sym_table[58].val’) +wanconfig.c:1385: error: ‘WAN_FR_ESF’ undeclared here (not in a function) +wanconfig.c:1385: error: initializer element is not constant +wanconfig.c:1385: error: (near initialization for ‘sym_table[59].val’) +wanconfig.c:1386: error: ‘WAN_FR_NCRC4’ undeclared here (not in a function) +wanconfig.c:1386: error: initializer element is not constant +wanconfig.c:1386: error: (near initialization for ‘sym_table[60].val’) +wanconfig.c:1387: error: ‘WAN_FR_CRC4’ undeclared here (not in a function) +wanconfig.c:1387: error: initializer element is not constant +wanconfig.c:1387: error: (near initialization for ‘sym_table[61].val’) +wanconfig.c:1388: error: ‘WAN_FR_UNFRAMED’ undeclared here (not in a function) +wanconfig.c:1388: error: initializer element is not constant +wanconfig.c:1388: error: (near initialization for ‘sym_table[62].val’) +wanconfig.c:1389: error: ‘WAN_FR_E3_G751’ undeclared here (not in a function) +wanconfig.c:1389: error: initializer element is not constant +wanconfig.c:1389: error: (near initialization for ‘sym_table[63].val’) +wanconfig.c:1390: error: ‘WAN_FR_E3_G832’ undeclared here (not in a function) +wanconfig.c:1390: error: initializer element is not constant +wanconfig.c:1390: error: (near initialization for ‘sym_table[64].val’) +wanconfig.c:1391: error: ‘WAN_FR_DS3_Cbit’ undeclared here (not in a function) +wanconfig.c:1391: error: initializer element is not constant +wanconfig.c:1391: error: (near initialization for ‘sym_table[65].val’) +wanconfig.c:1392: error: ‘WAN_FR_DS3_M13’ undeclared here (not in a function) +wanconfig.c:1392: error: initializer element is not constant +wanconfig.c:1392: error: (near initialization for ‘sym_table[66].val’) +wanconfig.c:1393: error: ‘WAN_T1_LBO_0_DB’ undeclared here (not in a function) +wanconfig.c:1393: error: initializer element is not constant +wanconfig.c:1393: error: (near initialization for ‘sym_table[67].val’) +wanconfig.c:1394: error: ‘WAN_T1_LBO_75_DB’ undeclared here (not in a function) +wanconfig.c:1394: error: initializer element is not constant +wanconfig.c:1394: error: (near initialization for ‘sym_table[68].val’) +wanconfig.c:1395: error: ‘WAN_T1_LBO_15_DB’ undeclared here (not in a function) +wanconfig.c:1395: error: initializer element is not constant +wanconfig.c:1395: error: (near initialization for ‘sym_table[69].val’) +wanconfig.c:1396: error: ‘WAN_T1_LBO_225_DB’ undeclared here (not in a function) +wanconfig.c:1396: error: initializer element is not constant +wanconfig.c:1396: error: (near initialization for ‘sym_table[70].val’) +wanconfig.c:1397: error: ‘WAN_T1_0_110’ undeclared here (not in a function) +wanconfig.c:1397: error: initializer element is not constant +wanconfig.c:1397: error: (near initialization for ‘sym_table[71].val’) +wanconfig.c:1398: error: ‘WAN_T1_110_220’ undeclared here (not in a function) +wanconfig.c:1398: error: initializer element is not constant +wanconfig.c:1398: error: (near initialization for ‘sym_table[72].val’) +wanconfig.c:1399: error: ‘WAN_T1_220_330’ undeclared here (not in a function) +wanconfig.c:1399: error: initializer element is not constant +wanconfig.c:1399: error: (near initialization for ‘sym_table[73].val’) +wanconfig.c:1400: error: ‘WAN_T1_330_440’ undeclared here (not in a function) +wanconfig.c:1400: error: initializer element is not constant +wanconfig.c:1400: error: (near initialization for ‘sym_table[74].val’) +wanconfig.c:1401: error: ‘WAN_T1_440_550’ undeclared here (not in a function) +wanconfig.c:1401: error: initializer element is not constant +wanconfig.c:1401: error: (near initialization for ‘sym_table[75].val’) +wanconfig.c:1402: error: ‘WAN_T1_550_660’ undeclared here (not in a function) +wanconfig.c:1402: error: initializer element is not constant +wanconfig.c:1402: error: (near initialization for ‘sym_table[76].val’) +wanconfig.c:1403: error: ‘WAN_T1_0_133’ undeclared here (not in a function) +wanconfig.c:1403: error: initializer element is not constant +wanconfig.c:1403: error: (near initialization for ‘sym_table[77].val’) +wanconfig.c:1404: error: ‘WAN_T1_133_266’ undeclared here (not in a function) +wanconfig.c:1404: error: initializer element is not constant +wanconfig.c:1404: error: (near initialization for ‘sym_table[78].val’) +wanconfig.c:1405: error: ‘WAN_T1_266_399’ undeclared here (not in a function) +wanconfig.c:1405: error: initializer element is not constant +wanconfig.c:1405: error: (near initialization for ‘sym_table[79].val’) +wanconfig.c:1406: error: ‘WAN_T1_399_533’ undeclared here (not in a function) +wanconfig.c:1406: error: initializer element is not constant +wanconfig.c:1406: error: (near initialization for ‘sym_table[80].val’) +wanconfig.c:1407: error: ‘WAN_T1_533_655’ undeclared here (not in a function) +wanconfig.c:1407: error: initializer element is not constant +wanconfig.c:1407: error: (near initialization for ‘sym_table[81].val’) +wanconfig.c:1408: error: ‘WAN_E1_120’ undeclared here (not in a function) +wanconfig.c:1408: error: initializer element is not constant +wanconfig.c:1408: error: (near initialization for ‘sym_table[82].val’) +wanconfig.c:1409: error: ‘WAN_E1_75’ undeclared here (not in a function) +wanconfig.c:1409: error: initializer element is not constant +wanconfig.c:1409: error: (near initialization for ‘sym_table[83].val’) +wanconfig.c:1410: error: ‘WAN_NORMAL_CLK’ undeclared here (not in a function) +wanconfig.c:1410: error: initializer element is not constant +wanconfig.c:1410: error: (near initialization for ‘sym_table[84].val’) +wanconfig.c:1411: error: ‘WAN_MASTER_CLK’ undeclared here (not in a function) +wanconfig.c:1411: error: initializer element is not constant +wanconfig.c:1411: error: (near initialization for ‘sym_table[85].val’) +wanconfig.c:1412: error: ‘WANOPT_FE_OSC_CLOCK’ undeclared here (not in a function) +wanconfig.c:1412: error: initializer element is not constant +wanconfig.c:1412: error: (near initialization for ‘sym_table[86].val’) +wanconfig.c:1413: error: ‘WANOPT_FE_LINE_CLOCK’ undeclared here (not in a function) +wanconfig.c:1413: error: initializer element is not constant +wanconfig.c:1413: error: (near initialization for ‘sym_table[87].val’) +wanconfig.c:1414: error: ‘WAN_TE1_SIG_CAS’ undeclared here (not in a function) +wanconfig.c:1414: error: initializer element is not constant +wanconfig.c:1414: error: (near initialization for ‘sym_table[88].val’) +wanconfig.c:1415: error: ‘WAN_TE1_SIG_CCS’ undeclared here (not in a function) +wanconfig.c:1415: error: initializer element is not constant +wanconfig.c:1415: error: (near initialization for ‘sym_table[89].val’) +wanconfig.c:1418: error: ‘WAN_TE3_RDEVICE_ADTRAN’ undeclared here (not in a function) +wanconfig.c:1418: error: initializer element is not constant +wanconfig.c:1418: error: (near initialization for ‘sym_table[90].val’) +wanconfig.c:1419: error: ‘WAN_TE3_RDEVICE_DIGITALLINK’ undeclared here (not in a function) +wanconfig.c:1419: error: initializer element is not constant +wanconfig.c:1419: error: (near initialization for ‘sym_table[91].val’) +wanconfig.c:1420: error: ‘WAN_TE3_RDEVICE_KENTROX’ undeclared here (not in a function) +wanconfig.c:1420: error: initializer element is not constant +wanconfig.c:1420: error: (near initialization for ‘sym_table[92].val’) +wanconfig.c:1421: error: ‘WAN_TE3_RDEVICE_LARSCOM’ undeclared here (not in a function) +wanconfig.c:1421: error: initializer element is not constant +wanconfig.c:1421: error: (near initialization for ‘sym_table[93].val’) +wanconfig.c:1422: error: ‘WAN_TE3_RDEVICE_VERILINK’ undeclared here (not in a function) +wanconfig.c:1422: error: initializer element is not constant +wanconfig.c:1422: error: (near initialization for ‘sym_table[94].val’) +wanconfig.c:1423: error: ‘WAN_TE3_LIU_LB_NORMAL’ undeclared here (not in a function) +wanconfig.c:1423: error: initializer element is not constant +wanconfig.c:1423: error: (near initialization for ‘sym_table[95].val’) +wanconfig.c:1424: error: ‘WAN_TE3_LIU_LB_ANALOG’ undeclared here (not in a function) +wanconfig.c:1424: error: initializer element is not constant +wanconfig.c:1424: error: (near initialization for ‘sym_table[96].val’) +wanconfig.c:1425: error: ‘WAN_TE3_LIU_LB_REMOTE’ undeclared here (not in a function) +wanconfig.c:1425: error: initializer element is not constant +wanconfig.c:1425: error: (near initialization for ‘sym_table[97].val’) +wanconfig.c:1426: error: ‘WAN_TE3_LIU_LB_DIGITAL’ undeclared here (not in a function) +wanconfig.c:1426: error: initializer element is not constant +wanconfig.c:1426: error: (near initialization for ‘sym_table[98].val’) +wanconfig.c:1428: error: initializer element is not constant +wanconfig.c:1428: error: (near initialization for ‘sym_table[99].val’) +wanconfig.c:1429: error: initializer element is not constant +wanconfig.c:1429: error: (near initialization for ‘sym_table[100].val’) +wanconfig.c:1430: error: initializer element is not constant +wanconfig.c:1430: error: (near initialization for ‘sym_table[101].val’) +wanconfig.c:1431: error: ‘WANCONFIG_LAPB’ undeclared here (not in a function) +wanconfig.c:1431: error: initializer element is not constant +wanconfig.c:1431: error: (near initialization for ‘sym_table[102].val’) +wanconfig.c:1432: error: ‘WANCONFIG_XDLC’ undeclared here (not in a function) +wanconfig.c:1432: error: initializer element is not constant +wanconfig.c:1432: error: (near initialization for ‘sym_table[103].val’) +wanconfig.c:1433: error: ‘WANCONFIG_TTY’ undeclared here (not in a function) +wanconfig.c:1433: error: initializer element is not constant +wanconfig.c:1433: error: (near initialization for ‘sym_table[104].val’) +wanconfig.c:1434: error: initializer element is not constant +wanconfig.c:1434: error: (near initialization for ‘sym_table[105].val’) +wanconfig.c:1435: error: initializer element is not constant +wanconfig.c:1435: error: (near initialization for ‘sym_table[106].val’) +wanconfig.c:1436: error: initializer element is not constant +wanconfig.c:1436: error: (near initialization for ‘sym_table[107].val’) +wanconfig.c:1437: error: ‘WANCONFIG_XMTP2’ undeclared here (not in a function) +wanconfig.c:1437: error: initializer element is not constant +wanconfig.c:1437: error: (near initialization for ‘sym_table[108].val’) +wanconfig.c:1438: error: ‘WANCONFIG_LAPD’ undeclared here (not in a function) +wanconfig.c:1438: error: initializer element is not constant +wanconfig.c:1438: error: (near initialization for ‘sym_table[109].val’) +wanconfig.c:1439: error: initializer element is not constant +wanconfig.c:1439: error: (near initialization for ‘sym_table[110].val’) +wanconfig.c:1440: error: initializer element is not constant +wanconfig.c:1440: error: (near initialization for ‘sym_table[111].val’) +wanconfig.c:1441: error: initializer element is not constant +wanconfig.c:1441: error: (near initialization for ‘sym_table[112].val’) +wanconfig.c:1442: error: initializer element is not constant +wanconfig.c:1442: error: (near initialization for ‘sym_table[113].val’) +wanconfig.c:1443: error: initializer element is not constant +wanconfig.c:1443: error: (near initialization for ‘sym_table[114].val’) +wanconfig.c:1446: error: ‘WANOPT_SS7_ANSI’ undeclared here (not in a function) +wanconfig.c:1446: error: initializer element is not constant +wanconfig.c:1446: error: (near initialization for ‘sym_table[115].val’) +wanconfig.c:1447: error: ‘WANOPT_SS7_ITU’ undeclared here (not in a function) +wanconfig.c:1447: error: initializer element is not constant +wanconfig.c:1447: error: (near initialization for ‘sym_table[116].val’) +wanconfig.c:1448: error: ‘WANOPT_SS7_NTT’ undeclared here (not in a function) +wanconfig.c:1448: error: initializer element is not constant +wanconfig.c:1448: error: (near initialization for ‘sym_table[117].val’) +wanconfig.c:1450: error: ‘WANOPT_SS7_FISU’ undeclared here (not in a function) +wanconfig.c:1450: error: initializer element is not constant +wanconfig.c:1450: error: (near initialization for ‘sym_table[118].val’) +wanconfig.c:1451: error: ‘WANOPT_SS7_LSSU’ undeclared here (not in a function) +wanconfig.c:1451: error: initializer element is not constant +wanconfig.c:1451: error: (near initialization for ‘sym_table[119].val’) +wanconfig.c:1453: error: ‘WANOPT_SS7_MODE_128’ undeclared here (not in a function) +wanconfig.c:1453: error: initializer element is not constant +wanconfig.c:1453: error: (near initialization for ‘sym_table[120].val’) +wanconfig.c:1454: error: ‘WANOPT_SS7_MODE_4096’ undeclared here (not in a function) +wanconfig.c:1454: error: initializer element is not constant +wanconfig.c:1454: error: (near initialization for ‘sym_table[121].val’) +wanconfig.c:1456: error: ‘WANOPT_S50X’ undeclared here (not in a function) +wanconfig.c:1456: error: initializer element is not constant +wanconfig.c:1456: error: (near initialization for ‘sym_table[122].val’) +wanconfig.c:1457: error: ‘WANOPT_S51X’ undeclared here (not in a function) +wanconfig.c:1457: error: initializer element is not constant +wanconfig.c:1457: error: (near initialization for ‘sym_table[123].val’) +wanconfig.c:1458: error: ‘WANOPT_ADSL’ undeclared here (not in a function) +wanconfig.c:1458: error: initializer element is not constant +wanconfig.c:1458: error: (near initialization for ‘sym_table[124].val’) +wanconfig.c:1459: error: initializer element is not constant +wanconfig.c:1459: error: (near initialization for ‘sym_table[125].val’) +wanconfig.c:1460: error: ‘WANOPT_AFT’ undeclared here (not in a function) +wanconfig.c:1460: error: initializer element is not constant +wanconfig.c:1460: error: (near initialization for ‘sym_table[126].val’) +wanconfig.c:1463: error: ‘RFC_MODE_BRIDGED_ETH_LLC’ undeclared here (not in a function) +wanconfig.c:1463: error: initializer element is not constant +wanconfig.c:1463: error: (near initialization for ‘sym_table[127].val’) +wanconfig.c:1464: error: ‘RFC_MODE_BRIDGED_ETH_VC’ undeclared here (not in a function) +wanconfig.c:1464: error: initializer element is not constant +wanconfig.c:1464: error: (near initialization for ‘sym_table[128].val’) +wanconfig.c:1465: error: ‘RFC_MODE_ROUTED_IP_LLC’ undeclared here (not in a function) +wanconfig.c:1465: error: initializer element is not constant +wanconfig.c:1465: error: (near initialization for ‘sym_table[129].val’) +wanconfig.c:1466: error: ‘RFC_MODE_ROUTED_IP_VC’ undeclared here (not in a function) +wanconfig.c:1466: error: initializer element is not constant +wanconfig.c:1466: error: (near initialization for ‘sym_table[130].val’) +wanconfig.c:1467: error: ‘RFC_MODE_PPP_LLC’ undeclared here (not in a function) +wanconfig.c:1467: error: initializer element is not constant +wanconfig.c:1467: error: (near initialization for ‘sym_table[131].val’) +wanconfig.c:1468: error: ‘RFC_MODE_PPP_VC’ undeclared here (not in a function) +wanconfig.c:1468: error: initializer element is not constant +wanconfig.c:1468: error: (near initialization for ‘sym_table[132].val’) +wanconfig.c:1469: error: ‘RFC_MODE_STACK_VC’ undeclared here (not in a function) +wanconfig.c:1469: error: initializer element is not constant +wanconfig.c:1469: error: (near initialization for ‘sym_table[133].val’) +wanconfig.c:1472: error: initializer element is not constant +wanconfig.c:1472: error: (near initialization for ‘sym_table[134].val’) +wanconfig.c:1473: error: initializer element is not constant +wanconfig.c:1473: error: (near initialization for ‘sym_table[135].val’) +wanconfig.c:1474: error: ‘LAN_INTERFACE’ undeclared here (not in a function) +wanconfig.c:1474: error: initializer element is not constant +wanconfig.c:1474: error: (near initialization for ‘sym_table[136].val’) +wanconfig.c:1475: error: ‘WAN_INTERFACE’ undeclared here (not in a function) +wanconfig.c:1475: error: initializer element is not constant +wanconfig.c:1475: error: (near initialization for ‘sym_table[137].val’) +wanconfig.c:1477: error: ‘WANOPT_ADSL_T1_413’ undeclared here (not in a function) +wanconfig.c:1477: error: initializer element is not constant +wanconfig.c:1477: error: (near initialization for ‘sym_table[138].val’) +wanconfig.c:1478: error: ‘WANOPT_ADSL_G_LITE’ undeclared here (not in a function) +wanconfig.c:1478: error: initializer element is not constant +wanconfig.c:1478: error: (near initialization for ‘sym_table[139].val’) +wanconfig.c:1479: error: ‘WANOPT_ADSL_G_DMT’ undeclared here (not in a function) +wanconfig.c:1479: error: initializer element is not constant +wanconfig.c:1479: error: (near initialization for ‘sym_table[140].val’) +wanconfig.c:1480: error: ‘WANOPT_ADSL_ALCATEL_1_4’ undeclared here (not in a function) +wanconfig.c:1480: error: initializer element is not constant +wanconfig.c:1480: error: (near initialization for ‘sym_table[141].val’) +wanconfig.c:1481: error: ‘WANOPT_ADSL_ALCATEL’ undeclared here (not in a function) +wanconfig.c:1481: error: initializer element is not constant +wanconfig.c:1481: error: (near initialization for ‘sym_table[142].val’) +wanconfig.c:1482: error: ‘WANOPT_ADSL_MULTIMODE’ undeclared here (not in a function) +wanconfig.c:1482: error: initializer element is not constant +wanconfig.c:1482: error: (near initialization for ‘sym_table[143].val’) +wanconfig.c:1483: error: ‘WANOPT_ADSL_T1_413_AUTO’ undeclared here (not in a function) +wanconfig.c:1483: error: initializer element is not constant +wanconfig.c:1483: error: (near initialization for ‘sym_table[144].val’) +wanconfig.c:1484: error: ‘WANOPT_ADSL_TRELLIS_ENABLE’ undeclared here (not in a function) +wanconfig.c:1484: error: initializer element is not constant +wanconfig.c:1484: error: (near initialization for ‘sym_table[145].val’) +wanconfig.c:1485: error: ‘WANOPT_ADSL_TRELLIS_DISABLE’ undeclared here (not in a function) +wanconfig.c:1485: error: initializer element is not constant +wanconfig.c:1485: error: (near initialization for ‘sym_table[146].val’) +wanconfig.c:1486: error: ‘WANOPT_ADSL_TRELLIS_LITE_ONLY_DISABLE’ undeclared here (not in a function) +wanconfig.c:1486: error: initializer element is not constant +wanconfig.c:1486: error: (near initialization for ‘sym_table[147].val’) +wanconfig.c:1487: error: ‘WANOPT_ADSL_0DB_CODING_GAIN’ undeclared here (not in a function) +wanconfig.c:1487: error: initializer element is not constant +wanconfig.c:1487: error: (near initialization for ‘sym_table[148].val’) +wanconfig.c:1488: error: ‘WANOPT_ADSL_1DB_CODING_GAIN’ undeclared here (not in a function) +wanconfig.c:1488: error: initializer element is not constant +wanconfig.c:1488: error: (near initialization for ‘sym_table[149].val’) +wanconfig.c:1489: error: ‘WANOPT_ADSL_2DB_CODING_GAIN’ undeclared here (not in a function) +wanconfig.c:1489: error: initializer element is not constant +wanconfig.c:1489: error: (near initialization for ‘sym_table[150].val’) +wanconfig.c:1490: error: ‘WANOPT_ADSL_3DB_CODING_GAIN’ undeclared here (not in a function) +wanconfig.c:1490: error: initializer element is not constant +wanconfig.c:1490: error: (near initialization for ‘sym_table[151].val’) +wanconfig.c:1491: error: ‘WANOPT_ADSL_4DB_CODING_GAIN’ undeclared here (not in a function) +wanconfig.c:1491: error: initializer element is not constant +wanconfig.c:1491: error: (near initialization for ‘sym_table[152].val’) +wanconfig.c:1492: error: ‘WANOPT_ADSL_5DB_CODING_GAIN’ undeclared here (not in a function) +wanconfig.c:1492: error: initializer element is not constant +wanconfig.c:1492: error: (near initialization for ‘sym_table[153].val’) +wanconfig.c:1493: error: ‘WANOPT_ADSL_6DB_CODING_GAIN’ undeclared here (not in a function) +wanconfig.c:1493: error: initializer element is not constant +wanconfig.c:1493: error: (near initialization for ‘sym_table[154].val’) +wanconfig.c:1494: error: ‘WANOPT_ADSL_7DB_CODING_GAIN’ undeclared here (not in a function) +wanconfig.c:1494: error: initializer element is not constant +wanconfig.c:1494: error: (near initialization for ‘sym_table[155].val’) +wanconfig.c:1495: error: ‘WANOPT_ADSL_AUTO_CODING_GAIN’ undeclared here (not in a function) +wanconfig.c:1495: error: initializer element is not constant +wanconfig.c:1495: error: (near initialization for ‘sym_table[156].val’) +wanconfig.c:1496: error: ‘WANOPT_ADSL_RX_BIN_DISABLE’ undeclared here (not in a function) +wanconfig.c:1496: error: initializer element is not constant +wanconfig.c:1496: error: (near initialization for ‘sym_table[157].val’) +wanconfig.c:1497: error: ‘WANOPT_ADSL_RX_BIN_ENABLE’ undeclared here (not in a function) +wanconfig.c:1497: error: initializer element is not constant +wanconfig.c:1497: error: (near initialization for ‘sym_table[158].val’) +wanconfig.c:1498: error: ‘WANOPT_ADSL_FRAMING_TYPE_0’ undeclared here (not in a function) +wanconfig.c:1498: error: initializer element is not constant +wanconfig.c:1498: error: (near initialization for ‘sym_table[159].val’) +wanconfig.c:1499: error: ‘WANOPT_ADSL_FRAMING_TYPE_1’ undeclared here (not in a function) +wanconfig.c:1499: error: initializer element is not constant +wanconfig.c:1499: error: (near initialization for ‘sym_table[160].val’) +wanconfig.c:1500: error: ‘WANOPT_ADSL_FRAMING_TYPE_2’ undeclared here (not in a function) +wanconfig.c:1500: error: initializer element is not constant +wanconfig.c:1500: error: (near initialization for ‘sym_table[161].val’) +wanconfig.c:1501: error: ‘WANOPT_ADSL_FRAMING_TYPE_3’ undeclared here (not in a function) +wanconfig.c:1501: error: initializer element is not constant +wanconfig.c:1501: error: (near initialization for ‘sym_table[162].val’) +wanconfig.c:1502: error: ‘WANOPT_ADSL_EXPANDED_EXCHANGE’ undeclared here (not in a function) +wanconfig.c:1502: error: initializer element is not constant +wanconfig.c:1502: error: (near initialization for ‘sym_table[163].val’) +wanconfig.c:1503: error: ‘WANOPT_ADSL_SHORT_EXCHANGE’ undeclared here (not in a function) +wanconfig.c:1503: error: initializer element is not constant +wanconfig.c:1503: error: (near initialization for ‘sym_table[164].val’) +wanconfig.c:1504: error: ‘WANOPT_ADSL_CLOCK_CRYSTAL’ undeclared here (not in a function) +wanconfig.c:1504: error: initializer element is not constant +wanconfig.c:1504: error: (near initialization for ‘sym_table[165].val’) +wanconfig.c:1505: error: ‘WANOPT_ADSL_CLOCK_OSCILLATOR’ undeclared here (not in a function) +wanconfig.c:1505: error: initializer element is not constant +wanconfig.c:1505: error: (near initialization for ‘sym_table[166].val’) +wanconfig.c:1507: error: ‘IBM4680’ undeclared here (not in a function) +wanconfig.c:1507: error: initializer element is not constant +wanconfig.c:1507: error: (near initialization for ‘sym_table[167].val’) +wanconfig.c:1508: error: initializer element is not constant +wanconfig.c:1508: error: (near initialization for ‘sym_table[168].val’) +wanconfig.c:1509: error: ‘NCR2126’ undeclared here (not in a function) +wanconfig.c:1509: error: initializer element is not constant +wanconfig.c:1509: error: (near initialization for ‘sym_table[169].val’) +wanconfig.c:1510: error: ‘NCR2127’ undeclared here (not in a function) +wanconfig.c:1510: error: initializer element is not constant +wanconfig.c:1510: error: (near initialization for ‘sym_table[170].val’) +wanconfig.c:1511: error: ‘NCR1255’ undeclared here (not in a function) +wanconfig.c:1511: error: initializer element is not constant +wanconfig.c:1511: error: (near initialization for ‘sym_table[171].val’) +wanconfig.c:1512: error: ‘NCR7000’ undeclared here (not in a function) +wanconfig.c:1512: error: initializer element is not constant +wanconfig.c:1512: error: (near initialization for ‘sym_table[172].val’) +wanconfig.c:1513: error: ‘ICL’ undeclared here (not in a function) +wanconfig.c:1513: error: initializer element is not constant +wanconfig.c:1513: error: (near initialization for ‘sym_table[173].val’) +wanconfig.c:1518: error: ‘WANOPT_DSP_HPAD’ undeclared here (not in a function) +wanconfig.c:1518: error: initializer element is not constant +wanconfig.c:1518: error: (near initialization for ‘sym_table[174].val’) +wanconfig.c:1519: error: ‘WANOPT_DSP_TPAD’ undeclared here (not in a function) +wanconfig.c:1519: error: initializer element is not constant +wanconfig.c:1519: error: (near initialization for ‘sym_table[175].val’) +wanconfig.c:1521: error: ‘WANOPT_AUTO’ undeclared here (not in a function) +wanconfig.c:1521: error: initializer element is not constant +wanconfig.c:1521: error: (near initialization for ‘sym_table[176].val’) +wanconfig.c:1522: error: ‘WANOPT_MANUAL’ undeclared here (not in a function) +wanconfig.c:1522: error: initializer element is not constant +wanconfig.c:1522: error: (near initialization for ‘sym_table[177].val’) +wanconfig.c:1525: error: ‘WANOPT_TWO_WAY_ALTERNATE’ undeclared here (not in a function) +wanconfig.c:1525: error: initializer element is not constant +wanconfig.c:1525: error: (near initialization for ‘sym_table[178].val’) +wanconfig.c:1526: error: ‘WANOPT_TWO_WAY_SIMULTANEOUS’ undeclared here (not in a function) +wanconfig.c:1526: error: initializer element is not constant +wanconfig.c:1526: error: (near initialization for ‘sym_table[179].val’) +wanconfig.c:1527: error: ‘WANOPT_PRI_DISC_ON_NO_RESP’ undeclared here (not in a function) +wanconfig.c:1527: error: initializer element is not constant +wanconfig.c:1527: error: (near initialization for ‘sym_table[180].val’) +wanconfig.c:1528: error: ‘WANOPT_PRI_SNRM_ON_NO_RESP’ undeclared here (not in a function) +wanconfig.c:1528: error: initializer element is not constant +wanconfig.c:1528: error: (near initialization for ‘sym_table[181].val’) +wanconfig.c:1530: error: ‘WP_NONE’ undeclared here (not in a function) +wanconfig.c:1530: error: initializer element is not constant +wanconfig.c:1530: error: (near initialization for ‘sym_table[182].val’) +wanconfig.c:1531: error: ‘WP_SLINEAR’ undeclared here (not in a function) +wanconfig.c:1531: error: initializer element is not constant +wanconfig.c:1531: error: (near initialization for ‘sym_table[183].val’) +wanconfig.c:1533: error: ‘WAN_TDMV_ALAW’ undeclared here (not in a function) +wanconfig.c:1533: error: initializer element is not constant +wanconfig.c:1533: error: (near initialization for ‘sym_table[184].val’) +wanconfig.c:1534: error: ‘WAN_TDMV_MULAW’ undeclared here (not in a function) +wanconfig.c:1534: error: initializer element is not constant +wanconfig.c:1534: error: (near initialization for ‘sym_table[185].val’) +wanconfig.c: In function ‘main’: +wanconfig.c:1556: error: ‘WANPIPE_VERSION_BETA’ undeclared (first use in this function) +wanconfig.c:1556: error: (Each undeclared identifier is reported only once +wanconfig.c:1556: error: for each function it appears in.) +wanconfig.c:1558: error: ‘WANPIPE_VERSION’ undeclared (first use in this function) +wanconfig.c:1558: error: ‘WANPIPE_SUB_VERSION’ undeclared (first use in this function) +wanconfig.c:1558: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ +wanconfig.c:1558: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:1561: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ +wanconfig.c:1561: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:1632: error: ‘WANPIPE_COPYRIGHT_DATES’ undeclared (first use in this function) +wanconfig.c:1632: error: ‘WANPIPE_COMPANY’ undeclared (first use in this function) +wanconfig.c:1632: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c:1632: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ +wanconfig.c:1632: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:1632: warning: format ‘%s’ expects type ‘char *’, but argument 5 has type ‘struct look_up_t *’ +wanconfig.c:1636: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c:1636: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ +wanconfig.c:1636: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:1636: warning: format ‘%s’ expects type ‘char *’, but argument 5 has type ‘struct look_up_t *’ +wanconfig.c:1743: warning: comparison between pointer and integer +wanconfig.c:1745: warning: format ‘%d’ expects type ‘int’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:1749: warning: comparison between pointer and integer +wanconfig.c:1751: warning: format ‘%d’ expects type ‘int’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c: In function ‘startup’: +wanconfig.c:1934: warning: comparison between pointer and integer +wanconfig.c: In function ‘wp_shutdown’: +wanconfig.c:2011: warning: comparison between pointer and integer +wanconfig.c: In function ‘router_down’: +wanconfig.c:2033: error: size of array ‘filename’ has non-integer type +wanconfig.c:2037: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2037: error: ‘wandev_conf_t’ undeclared (first use in this function) +wanconfig.c:2037: warning: passing argument 1 of ‘malloc’ makes integer from pointer without a cast +wanconfig.c:2037: warning: statement with no effect +wanconfig.c:2038: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2047: warning: comparison between pointer and integer +wanconfig.c:2071: error: ‘ROUTER_DOWN’ undeclared (first use in this function) +wanconfig.c:2071: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2071: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast +wanconfig.c:2093: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2093: error: ‘look_up_t’ has no member named ‘config_id’ +wanconfig.c:2094: warning: implicit declaration of function ‘update_adsl_vci_vpi_list’ +wanconfig.c:2094: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2094: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2094: error: request for member ‘adsl’ in something not a structure or union +wanconfig.c:2094: error: request for member ‘vcivpi_list’ in something not a structure or union +wanconfig.c:2095: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2095: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2095: error: request for member ‘adsl’ in something not a structure or union +wanconfig.c:2095: error: request for member ‘vcivpi_num’ in something not a structure or union +wanconfig.c:2098: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2099: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2099: warning: statement with no effect +wanconfig.c: In function ‘router_ifdel’: +wanconfig.c:2111: error: size of array ‘filename’ has non-integer type +wanconfig.c:2112: error: size of array ‘devicename’ has non-integer type +wanconfig.c:2118: warning: comparison between pointer and integer +wanconfig.c:2128: warning: comparison between pointer and integer +wanconfig.c:2148: error: ‘ROUTER_IFDEL’ undeclared (first use in this function) +wanconfig.c:2148: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast +wanconfig.c: In function ‘configure’: +wanconfig.c:2201: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:2201: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:2201: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:2201: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:2201: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:2201: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:2207: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c: In function ‘build_linkdef_list’: +wanconfig.c:2292: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2292: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:2297: warning: passing argument 2 of ‘read_conf_section’ from incompatible pointer type +wanconfig.c:2299: error: ‘link_def_t’ has no member named ‘next’ +wanconfig.c:2299: warning: statement with no effect +wanconfig.c: In function ‘build_chandef_list’: +wanconfig.c:2357: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2357: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:2383: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c:2388: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c:2433: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c:2439: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c:2474: error: ‘chan_def_t’ has no member named ‘next’ +wanconfig.c:2475: error: ‘chan_def_t’ has no member named ‘next’ +wanconfig.c:2475: warning: assignment from incompatible pointer type +wanconfig.c:2477: error: ‘chan_def_t’ has no member named ‘next’ +wanconfig.c:2477: warning: statement with no effect +wanconfig.c:2481: error: ‘chan_def_t’ has no member named ‘link’ +wanconfig.c:2481: warning: statement with no effect +wanconfig.c: In function ‘configure_link’: +wanconfig.c:2498: error: size of array ‘filename’ has non-integer type +wanconfig.c:2511: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2512: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2512: error: ‘look_up_t’ has no member named ‘data’ +wanconfig.c:2512: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2512: error: ‘look_up_t’ has no member named ‘data’ +wanconfig.c:2513: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2514: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2514: warning: statement with no effect +wanconfig.c:2517: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2517: error: ‘wandev_conf_t’ undeclared (first use in this function) +wanconfig.c:2517: warning: passing argument 1 of ‘malloc’ makes integer from pointer without a cast +wanconfig.c:2517: warning: statement with no effect +wanconfig.c:2518: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2522: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2522: warning: passing argument 3 of ‘memset’ makes integer from pointer without a cast +wanconfig.c:2523: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2523: error: ‘look_up_t’ has no member named ‘magic’ +wanconfig.c:2523: error: ‘ROUTER_MAGIC’ undeclared (first use in this function) +wanconfig.c:2523: warning: statement with no effect +wanconfig.c:2524: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2524: error: ‘look_up_t’ has no member named ‘config_id’ +wanconfig.c:2524: warning: statement with no effect +wanconfig.c:2542: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2545: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2545: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2562: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:2572: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2572: error: ‘look_up_t’ has no member named ‘config_id’ +wanconfig.c:2578: error: ‘chan_def_t’ has no member named ‘next’ +wanconfig.c:2578: warning: assignment from incompatible pointer type +wanconfig.c:2591: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2591: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2591: error: request for member ‘fr’ in something not a structure or union +wanconfig.c:2591: error: request for member ‘dlci’ in something not a structure or union +wanconfig.c:2591: error: incompatible types in assignment +wanconfig.c:2591: warning: statement with no effect +wanconfig.c:2592: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2592: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2592: error: request for member ‘fr’ in something not a structure or union +wanconfig.c:2592: error: request for member ‘dlci’ in something not a structure or union +wanconfig.c:2592: error: invalid operands to binary > +wanconfig.c:2593: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2593: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2593: error: request for member ‘fr’ in something not a structure or union +wanconfig.c:2593: error: request for member ‘dlci’ in something not a structure or union +wanconfig.c:2593: error: incompatible types in assignment +wanconfig.c:2593: warning: statement with no effect +wanconfig.c:2603: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2603: error: ‘look_up_t’ has no member named ‘config_id’ +wanconfig.c:2604: warning: implicit declaration of function ‘read_adsl_vci_vpi_list’ +wanconfig.c:2604: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2604: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2604: error: request for member ‘adsl’ in something not a structure or union +wanconfig.c:2604: error: request for member ‘vcivpi_list’ in something not a structure or union +wanconfig.c:2605: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2605: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2605: error: request for member ‘adsl’ in something not a structure or union +wanconfig.c:2605: error: request for member ‘vcivpi_num’ in something not a structure or union +wanconfig.c:2621: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2621: error: ‘look_up_t’ has no member named ‘ft1’ +wanconfig.c:2621: warning: statement with no effect +wanconfig.c:2623: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2623: error: ‘look_up_t’ has no member named ‘ft1’ +wanconfig.c:2623: warning: statement with no effect +wanconfig.c:2628: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2628: error: ‘look_up_t’ has no member named ‘data’ +wanconfig.c:2628: warning: statement with no effect +wanconfig.c:2634: error: ‘chan_def_t’ has no member named ‘next’ +wanconfig.c:2634: warning: assignment from incompatible pointer type +wanconfig.c:2638: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2638: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2638: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:2639: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2639: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2639: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:2642: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2642: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2642: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:2645: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2645: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2645: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:2650: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:2650: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:2650: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:2650: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:2650: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:2650: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:2658: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c:2660: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2661: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2662: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2662: warning: statement with no effect +wanconfig.c:2664: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2664: error: ‘wanif_conf_t’ undeclared (first use in this function) +wanconfig.c:2664: warning: passing argument 1 of ‘malloc’ makes integer from pointer without a cast +wanconfig.c:2664: warning: statement with no effect +wanconfig.c:2665: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2670: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2670: warning: passing argument 3 of ‘memset’ makes integer from pointer without a cast +wanconfig.c:2671: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2671: error: ‘look_up_t’ has no member named ‘magic’ +wanconfig.c:2671: warning: statement with no effect +wanconfig.c:2672: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2672: error: ‘look_up_t’ has no member named ‘config_id’ +wanconfig.c:2672: warning: statement with no effect +wanconfig.c:2679: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2679: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2679: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c: In function ‘exec_link_cmd’: +wanconfig.c:2690: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2692: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ +wanconfig.c:2704: error: ‘ROUTER_VER’ undeclared (first use in this function) +wanconfig.c:2704: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast +wanconfig.c:2708: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:2710: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:2756: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:2774: error: ‘ROUTER_SETUP’ undeclared (first use in this function) +wanconfig.c:2774: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:2774: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast +wanconfig.c:2777: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:2779: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c: In function ‘configure_chan’: +wanconfig.c:2809: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2814: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2814: error: ‘look_up_t’ has no member named ‘name’ +wanconfig.c:2814: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2814: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2814: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:2816: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2816: error: ‘look_up_t’ has no member named ‘addr’ +wanconfig.c:2816: error: ‘WAN_ADDRESS_SZ’ undeclared (first use in this function) +wanconfig.c:2816: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2816: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:2819: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2819: error: ‘look_up_t’ has no member named ‘usedby’ +wanconfig.c:2819: error: ‘USED_BY_FIELD’ undeclared (first use in this function) +wanconfig.c:2819: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2819: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:2823: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2823: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2825: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2825: error: ‘look_up_t’ has no member named ‘label’ +wanconfig.c:2825: error: ‘WAN_IF_LABEL_SZ’ undeclared (first use in this function) +wanconfig.c:2825: warning: passing argument 3 of ‘memcpy’ makes integer from pointer without a cast +wanconfig.c:2832: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2832: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2839: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2839: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2858: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2864: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2864: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2872: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2872: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2915: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2915: error: ‘look_up_t’ has no member named ‘u’ +wanconfig.c:2916: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c: In function ‘exec_chan_cmd’: +wanconfig.c:2938: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2940: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ +wanconfig.c:2953: error: ‘ROUTER_IFNEW’ undeclared (first use in this function) +wanconfig.c:2953: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2953: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast +wanconfig.c:2955: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:2957: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:2970: error: ‘chan_def_t’ has no member named ‘link’ +wanconfig.c:2970: warning: initialization from incompatible pointer type +wanconfig.c:2973: warning: comparison between pointer and integer +wanconfig.c:2974: warning: comparison between pointer and integer +wanconfig.c:2975: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2975: error: ‘look_up_t’ has no member named ‘hwec’ +wanconfig.c:2975: error: request for member ‘enable’ in something not a structure or union +wanconfig.c:2977: warning: passing argument 1 of ‘config_hwec’ from incompatible pointer type +wanconfig.c:2984: warning: passing argument 1 of ‘enable_hwec’ from incompatible pointer type +wanconfig.c:2984: warning: passing argument 2 of ‘enable_hwec’ from incompatible pointer type +wanconfig.c:2986: warning: passing argument 1 of ‘release_hwec’ from incompatible pointer type +wanconfig.c:2996: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2996: error: ‘look_up_t’ has no member named ‘master’ +wanconfig.c:2996: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:2996: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:2998: error: ‘ROUTER_IFNEW_LAPB’ undeclared (first use in this function) +wanconfig.c:2998: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:2998: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast +wanconfig.c:2999: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:3001: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:3014: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:3014: error: ‘look_up_t’ has no member named ‘master’ +wanconfig.c:3014: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:3014: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:3016: error: ‘ROUTER_IFNEW_X25’ undeclared (first use in this function) +wanconfig.c:3016: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:3016: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast +wanconfig.c:3017: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:3019: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:3033: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:3033: error: ‘look_up_t’ has no member named ‘master’ +wanconfig.c:3033: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:3033: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:3034: error: ‘ROUTER_IFNEW_DSP’ undeclared (first use in this function) +wanconfig.c:3034: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:3034: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast +wanconfig.c:3035: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:3037: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:3061: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:3061: error: ‘look_up_t’ has no member named ‘master’ +wanconfig.c:3061: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:3061: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:3067: error: ‘ROUTER_IFNEW_LIP’ undeclared (first use in this function) +wanconfig.c:3067: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:3067: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast +wanconfig.c:3069: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:3071: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c: In function ‘conf_file_down’: +wanconfig.c:3820: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:3820: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:3822: warning: passing argument 1 of ‘router_down’ from incompatible pointer type +wanconfig.c:3795: warning: unused variable ‘devname’ +wanconfig.c: In function ‘has_config_changed’: +wanconfig.c:3909: error: ‘link_def_t’ has no member named ‘next’ +wanconfig.c:3909: warning: assignment from incompatible pointer type +wanconfig.c:3910: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:3910: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:3910: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:3910: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:3910: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:3910: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c: In function ‘free_device_link’: +wanconfig.c:3941: error: ‘link_def_t’ has no member named ‘next’ +wanconfig.c:3941: warning: assignment from incompatible pointer type +wanconfig.c:3942: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:3942: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:3942: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:3942: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:3942: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:3942: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:3955: error: ‘chan_def_t’ has no member named ‘next’ +wanconfig.c:3955: warning: assignment from incompatible pointer type +wanconfig.c:3957: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:3958: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:3966: error: ‘link_def_t’ has no member named ‘next’ +wanconfig.c:3966: warning: assignment from incompatible pointer type +wanconfig.c:3968: error: ‘link_def_t’ has no member named ‘next’ +wanconfig.c:3968: error: ‘link_def_t’ has no member named ‘next’ +wanconfig.c:3968: warning: statement with no effect +wanconfig.c:3970: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ +wanconfig.c:3971: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:3972: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c: In function ‘free_linkdefs’: +wanconfig.c:3999: error: ‘chan_def_t’ has no member named ‘next’ +wanconfig.c:3999: warning: assignment from incompatible pointer type +wanconfig.c:4001: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:4002: error: ‘chan_def_t’ has no member named ‘chanconf’ +wanconfig.c:4010: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:4011: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:4014: error: ‘link_def_t’ has no member named ‘next’ +wanconfig.c:4014: warning: assignment from incompatible pointer type +wanconfig.c: In function ‘device_syncup’: +wanconfig.c:4034: warning: passing argument 2 of ‘has_config_changed’ from incompatible pointer type +wanconfig.c: In function ‘start_chan’: +wanconfig.c:4083: error: ‘chan_def_t’ has no member named ‘next’ +wanconfig.c:4083: warning: assignment from incompatible pointer type +wanconfig.c:4087: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:4087: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:4087: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:4088: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:4088: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:4088: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:4091: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:4091: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:4091: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:4094: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:4094: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type +wanconfig.c:4094: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast +wanconfig.c:4098: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:4098: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:4098: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:4098: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:4098: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:4098: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:4105: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c: In function ‘start_link’: +wanconfig.c:4150: error: ‘link_def_t’ has no member named ‘next’ +wanconfig.c:4150: warning: assignment from incompatible pointer type +wanconfig.c:4151: warning: passing argument 2 of ‘has_config_changed’ from incompatible pointer type +wanconfig.c:4152: warning: passing argument 1 of ‘device_syncup’ from incompatible pointer type +wanconfig.c:4164: error: ‘link_def_t’ has no member named ‘next’ +wanconfig.c:4164: warning: assignment from incompatible pointer type +wanconfig.c:4166: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:4166: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:4166: warning: passing argument 1 of ‘strlen’ from incompatible pointer type +wanconfig.c:4166: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:4166: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:4166: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type +wanconfig.c:4171: warning: pointer type mismatch in conditional expression +wanconfig.c:4171: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c:4171: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘void *’ +wanconfig.c:4175: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ +wanconfig.c:4182: error: ‘link_def_t’ has no member named ‘linkconf’ +wanconfig.c:4182: error: ‘look_up_t’ has no member named ‘ft1’ +wanconfig.c:4182: warning: statement with no effect +wanconfig.c: In function ‘stop_link’: +wanconfig.c:4227: error: ‘link_def_t’ has no member named ‘next’ +wanconfig.c:4227: warning: assignment from incompatible pointer type +wanconfig.c:4232: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ +wanconfig.c:4234: warning: passing argument 1 of ‘router_down’ from incompatible pointer type +wanconfig.c: In function ‘debugging’: +wanconfig.c:4717: error: size of array ‘filename’ has non-integer type +wanconfig.c:4738: error: ‘union ’ has no member named ‘linkconf’ +wanconfig.c:4738: error: ‘wandev_conf_t’ undeclared (first use in this function) +wanconfig.c:4738: warning: passing argument 3 of ‘memset’ makes integer from pointer without a cast +wanconfig.c:4739: error: ‘union ’ has no member named ‘linkconf’ +wanconfig.c:4739: error: request for member ‘magic’ in something not a structure or union +wanconfig.c:4739: error: ‘ROUTER_MAGIC’ undeclared (first use in this function) +wanconfig.c:4739: warning: statement with no effect +wanconfig.c: In function ‘debug_read’: +wanconfig.c:4765: error: size of array ‘filename’ has non-integer type +wanconfig.c:4766: error: ‘wan_kernel_msg_t’ undeclared (first use in this function) +wanconfig.c:4766: warning: statement with no effect +wanconfig.c:4766: error: expected ‘;’ before ‘wan_kernel_msg’ +wanconfig.c:4787: error: ‘union ’ has no member named ‘linkconf’ +wanconfig.c:4787: error: ‘wandev_conf_t’ undeclared (first use in this function) +wanconfig.c:4787: warning: passing argument 3 of ‘memset’ makes integer from pointer without a cast +wanconfig.c:4788: error: ‘union ’ has no member named ‘linkconf’ +wanconfig.c:4788: error: request for member ‘magic’ in something not a structure or union +wanconfig.c:4788: error: ‘ROUTER_MAGIC’ undeclared (first use in this function) +wanconfig.c:4788: warning: statement with no effect +wanconfig.c:4794: error: ‘wan_kernel_msg’ undeclared (first use in this function) +wanconfig.c:4794: warning: passing argument 3 of ‘memset’ makes integer from pointer without a cast +wanconfig.c:4795: error: request for member ‘magic’ in something not a structure or union +wanconfig.c:4795: warning: statement with no effect +wanconfig.c:4796: error: request for member ‘max_len’ in something not a structure or union +wanconfig.c:4796: warning: statement with no effect +wanconfig.c:4797: error: request for member ‘data’ in something not a structure or union +wanconfig.c:4797: warning: statement with no effect +wanconfig.c:4798: error: request for member ‘data’ in something not a structure or union +wanconfig.c:4806: error: ‘ROUTER_DEBUG_READ’ undeclared (first use in this function) +wanconfig.c:4806: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast +wanconfig.c:4813: error: request for member ‘len’ in something not a structure or union +wanconfig.c:4815: error: request for member ‘len’ in something not a structure or union +wanconfig.c:4815: warning: comparison between pointer and integer +wanconfig.c:4816: error: request for member ‘data’ in something not a structure or union +wanconfig.c:4819: error: request for member ‘is_more’ in something not a structure or union +wanconfig.c:4828: error: request for member ‘data’ in something not a structure or union +wanconfig.c: At top level: +wanconfig.c:4834: error: expected ‘)’ before ‘*’ token +wanconfig.c:4870: error: expected ‘)’ before ‘*’ token +wanconfig.c: In function ‘parse_active_channel’: +wanconfig.c:4918: error: ‘ENABLE_ALL_CHANNELS’ undeclared (first use in this function) +wanconfig.c:4918: warning: return makes integer from pointer without a cast +make: *** [wanconfig] Error 1 diff --git a/util/wanconfig/wanconfig.c b/util/wanconfig/wanconfig.c index 5fcc916..e1460c1 100644 --- a/util/wanconfig/wanconfig.c +++ b/util/wanconfig/wanconfig.c @@ -580,10 +580,11 @@ key_word_t common_conftab[] = /* Common configuration parameters */ { "TDMV_DCHAN", offsetof(wandev_conf_t, tdmv_conf)+smemof(wan_tdmv_conf_t, dchan), DTYPE_UINT}, { "TDMV_HW_DTMF", offsetof(wandev_conf_t, tdmv_conf)+smemof(wan_tdmv_conf_t, hw_dtmf), DTYPE_UCHAR}, - { "HWEC_CLKSRC", offsetof(wandev_conf_t, tdmv_conf)+smemof(wan_hwec_conf_t, clk_src), DTYPE_UINT}, - { "HWEC_PERSIST_DISABLE", offsetof(wandev_conf_t, tdmv_conf)+smemof(wan_hwec_conf_t, persist_disable), DTYPE_UINT}, + { "HWEC_CLKSRC", offsetof(wandev_conf_t, hwec_conf)+smemof(wan_hwec_conf_t, clk_src), DTYPE_UINT}, + { "HWEC_PERSIST_DISABLE", offsetof(wandev_conf_t, hwec_conf)+smemof(wan_hwec_conf_t, persist_disable), DTYPE_UINT}, /* Keep backward compatibility */ - { "TDMV_HWEC_PERSIST_DISABLE", offsetof(wandev_conf_t, tdmv_conf)+smemof(wan_hwec_conf_t, persist_disable), DTYPE_UINT}, + { "TDMV_HWEC_PERSIST_DISABLE", offsetof(wandev_conf_t, hwec_conf)+smemof(wan_hwec_conf_t, persist_disable), DTYPE_UINT}, + { "HWEC_NOISE_REDUCTION", offsetof(wandev_conf_t, hwec_conf)+smemof(wan_hwec_conf_t, noise_reduction), DTYPE_UINT}, { "BAUDRATE", smemof(wandev_conf_t, bps), DTYPE_UINT }, { "MTU", smemof(wandev_conf_t, mtu), DTYPE_UINT }, diff --git a/util/wanpipemon/diff b/util/wanpipemon/diff new file mode 100644 index 0000000..043cc73 --- /dev/null +++ b/util/wanpipemon/diff @@ -0,0 +1,358 @@ +--- prot_trace.c 2007-09-30 21:43:09.000000000 -0400 ++++ /common/wantools/wanpipemon/prot_trace.c 2007-12-04 17:30:23.000000000 -0500 +@@ -76,12 +76,13 @@ + unsigned char dighex(unsigned char n); + int x25_call_request_decode (unsigned char *data, int len); + void trace_banner (wp_trace_output_iface_t *trace_iface, int *trace_started); ++int trace_hdlc_data(wanpipe_hdlc_engine_t *hdlc_eng, void *data, int len); + + static void decode_chdlc_ip_transaction(cisco_slarp_t *cisco_slarp); + static void print_ipv4_address(unsigned int address); +-static int decode_data_ipv4(unsigned char* data, unsigned short data_len); ++static int decode_data_ipv4(char* data, unsigned short data_len); + static char* decode_tcp_level_protocol(unsigned short port); +-static void print_data_in_hex(unsigned char* data, unsigned short data_len); ++static void print_data_in_hex(char* data, unsigned short data_len); + + int match_trace_criteria(unsigned char *pkt, int len, int *dlci) + { +@@ -114,7 +115,7 @@ + + date_string[0] = '\0'; + +- sprintf(date_string, "%5d", timestamp); ++ snprintf(date_string, 100, "%5d", timestamp); + + if (trace_iface->sec){ + char tmp_time[50]; +@@ -125,21 +126,21 @@ + time_tm = localtime(&time_val); + + strftime(tmp_time,sizeof(tmp_time)," %b",time_tm); +- sprintf(date_string+strlen(date_string), " %s ",tmp_time); ++ snprintf(date_string+strlen(date_string), 100-strlen(date_string), " %s ",tmp_time); + + strftime(tmp_time,sizeof(tmp_time),"%d",time_tm); +- sprintf(date_string+strlen(date_string), "%s ",tmp_time); ++ snprintf(date_string+strlen(date_string), 100-strlen(date_string), "%s ",tmp_time); + + strftime(tmp_time,sizeof(tmp_time),"%H",time_tm); +- sprintf(date_string+strlen(date_string), "%s:",tmp_time); ++ snprintf(date_string+strlen(date_string), 100-strlen(date_string), "%s:",tmp_time); + + strftime(tmp_time,sizeof(tmp_time),"%M",time_tm); +- sprintf(date_string+strlen(date_string), "%s:",tmp_time); ++ snprintf(date_string+strlen(date_string), 100-strlen(date_string), "%s:",tmp_time); + + strftime(tmp_time,sizeof(tmp_time),"%S",time_tm); +- sprintf(date_string+strlen(date_string), "%s",tmp_time); ++ snprintf(date_string+strlen(date_string), 100-strlen(date_string), "%s",tmp_time); + +- sprintf(date_string+strlen(date_string), " %-6lu [1/100s]",trace_iface->usec ); ++ snprintf(date_string+strlen(date_string), 100-strlen(date_string), " %-6lu [1/100s]",(unsigned long)trace_iface->usec ); + } + + printf("\n%s\tLen=%d\tTimeStamp=%s\n", +@@ -331,7 +332,7 @@ + if (code == 0x39) + return "Destination Absent"; + +- sprintf(buffer, "Unknown %02X", code); ++ snprintf(buffer, 25, "Unknown %02X", code); + + return buffer; + } +@@ -558,7 +559,7 @@ + if (code == 250) + return "Reset - user resynchronization"; + +- sprintf(buffer, "Unknown %d", code); ++ snprintf(buffer, 25, "Unknown %d", code); + + return buffer; + } +@@ -567,7 +568,7 @@ + static int decode_chdlc(wp_trace_output_iface_t *trace_iface, + int *trace_started) + { +- unsigned char *data = trace_iface->data; ++ char *data= (char*)trace_iface->data; + + int inf_frame=0; + cisco_header_t *cisco_header = (cisco_header_t *)&data[0]; +@@ -586,7 +587,7 @@ + case CISCO_PACKET_IP: + printf("CISCO Packet IP-v4\n\n"); + //decode data past Cisco header +- decode_data_ipv4((unsigned char*)(cisco_header + 1), ++ decode_data_ipv4((char*)(cisco_header + 1), + trace_iface->len - sizeof(cisco_header_t)); + break; + +@@ -661,7 +662,7 @@ + #define IP_V4 4 + #define IP_V4_IHLEN 5 + +-static int decode_data_ipv4(unsigned char* data, unsigned short data_len) ++static int decode_data_ipv4(char* data, unsigned short data_len) + { + iphdr_t *ip_hdr = (iphdr_t*)data; + struct tcphdr * tcp_hdr; +@@ -762,12 +763,10 @@ + case IPPROTO_RAW: /* 255 */ + printf("Raw IP packets"); + break; +- +-#if 0 ++ + case IPPROTO_MAX: + printf("IPPROTO_MAX"); + break; +-#endif + + default: + printf("Unknown (%d)\n", ip_hdr->w_ip_p); +@@ -843,7 +842,7 @@ + (unsigned int)(address & 0xFF000000) >>24); + } + +-static void print_data_in_hex(unsigned char* data, unsigned short data_len) ++static void print_data_in_hex(char* data, unsigned short data_len) + { + int i; + +@@ -1532,7 +1531,8 @@ + fwrite(&ph, sizeof(ph), 1, trace_iface->output_file); + } + +-static void get_ppp_magic_number(unsigned char* data, int len, char* outstr, char offset_flag) ++static void ++get_ppp_magic_number(char* data, int len, char* outstr, int max_len, char offset_flag) + { + if(offset_flag == 0){ + +@@ -1540,7 +1540,7 @@ + printf("%s invalid buffer length. Line: %d\n", __FUNCTION__, __LINE__); + return; + } +- sprintf(outstr, "\tMagic# %02X%02X%02X%02X", ++ snprintf(outstr, max_len, "\tMagic# %02X%02X%02X%02X", + (unsigned char)data[8], (unsigned char)data[9], + (unsigned char)data[10], (unsigned char)data[11]); + }else{ +@@ -1549,12 +1549,13 @@ + printf("%s invalid buffer length. Line: %d\n", __FUNCTION__, __LINE__); + return; + } +- sprintf(outstr, "\tMagic# %02X%02X%02X%02X", ++ snprintf(outstr, max_len, "\tMagic# %02X%02X%02X%02X", + (unsigned char)data[8+2], (unsigned char)data[8+3], + (unsigned char)data[8+4], (unsigned char)data[8+5]); + } + } + ++#define MAX_OUTSTR_LEN 1024 + static int decode_ppp(wp_trace_output_iface_t *trace_iface, + int *trace_started) + { +@@ -1562,10 +1563,10 @@ + int len = trace_iface->len; + int inf_frame=0; + unsigned short tmp_ushort; +- char outstr[1024]; ++ char outstr[MAX_OUTSTR_LEN]; + + trace_banner(trace_iface,trace_started); +- memset(outstr, 0x00, 1024); ++ memset(outstr, 0x00, MAX_OUTSTR_LEN); + + //print the data (including PPP header) + print_data_in_hex(data, len); +@@ -1591,58 +1592,58 @@ + + //pre-decodeing + if (tmp_ushort == 0x2180){ +- sprintf(outstr+strlen(outstr), "IPCP-v4 packet - "); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "IPCP-v4 packet - "); + } + + if (tmp_ushort == 0x5780){ +- sprintf(outstr+strlen(outstr), "IPCP-v6 packet - "); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "IPCP-v6 packet - "); + } + + if (tmp_ushort == 0x2B80){ +- sprintf(outstr+strlen(outstr), "IPXCP packet - "); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "IPXCP packet - "); + } + + if (tmp_ushort == 0x21C0){ +- sprintf(outstr+strlen(outstr), "LCP packet\tID 0x%02X - ", data[5]); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "LCP packet\tID 0x%02X - ", data[5]); + } + + //common decoding + switch(data[4]) { + case 1: +- sprintf(outstr+strlen(outstr), "Configure Request"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Configure Request"); + break; + case 2: +- sprintf(outstr+strlen(outstr), "Configure Ack\t"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Configure Ack\t"); + break; + case 3: +- sprintf(outstr+strlen(outstr), "Configure Nack\t"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Configure Nack\t"); + break; + case 4: +- sprintf(outstr+strlen(outstr), "Configure Reject"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Configure Reject"); + break; + case 5: +- sprintf(outstr+strlen(outstr), "Terminate Request"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Terminate Request"); + break; + case 6: +- sprintf(outstr+strlen(outstr), "Terminate Ack\t"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Terminate Ack\t"); + break; + case 7: +- sprintf(outstr+strlen(outstr), "Code Reject\t"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Code Reject\t"); + break; + case 8: +- sprintf(outstr+strlen(outstr), "Protocol Reject"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Protocol Reject"); + break; + case 9: +- sprintf(outstr+strlen(outstr), "Echo Request\t"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Echo Request\t"); + break; + case 10: +- sprintf(outstr+strlen(outstr), "Echo Reply\t"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Echo Reply\t"); + break; + case 11: +- sprintf(outstr+strlen(outstr), "Discard Request"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Discard Request"); + break; + default: +- sprintf(outstr+strlen(outstr), "Unknown type"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Unknown type"); + break; + } + +@@ -1651,16 +1652,24 @@ + //LCP + switch(data[4]) { + case 1: +- get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); ++ get_ppp_magic_number( ++ data, len, ++ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 1); + break; + case 2: +- get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); ++ get_ppp_magic_number( ++ data, len, ++ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 1); + break; + case 3: +- get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); ++ get_ppp_magic_number( ++ data, len, ++ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 1); + break; + case 4: +- get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); ++ get_ppp_magic_number( ++ data, len, ++ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 1); + break; + case 5: + case 6: +@@ -1669,13 +1678,19 @@ + ;//do nothing + break; + case 9: +- get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); ++ get_ppp_magic_number( ++ data, len, ++ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 0); + break; + case 10: +- get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); ++ get_ppp_magic_number( ++ data, len, ++ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 0); + break; + case 11: +- get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); ++ get_ppp_magic_number( ++ data, len, ++ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 0); + break; + default: + break; +@@ -1684,47 +1699,47 @@ + break; + + case 0x23C0: // PAP +- sprintf(outstr+strlen(outstr), "PAP packet - "); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "PAP packet - "); + switch(data[4]) { + case 1: +- sprintf(outstr+strlen(outstr), "Authenticate Request"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Authenticate Request"); + break; + case 2: +- sprintf(outstr+strlen(outstr), "Authenticate Ack"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Authenticate Ack"); + break; + case 3: +- sprintf(outstr+strlen(outstr), "Authenticate Nack"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Authenticate Nack"); + break; + default: +- sprintf(outstr+strlen(outstr), "Unknown type"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Unknown type"); + break; + } + break; + case 0x25C0: // LQR +- sprintf(outstr+strlen(outstr), "Link Quality Report"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Link Quality Report"); + break; + case 0x23C2: // CHAP +- sprintf(outstr+strlen(outstr), "CHAP packet - "); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "CHAP packet - "); + switch(data[4]) { + case 1: +- sprintf(outstr+strlen(outstr), "Challenge"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Challenge"); + break; + case 2: +- sprintf(outstr+strlen(outstr), "Responce"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Responce"); + break; + case 3: +- sprintf(outstr+strlen(outstr), "Success"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Success"); + break; + case 4: +- sprintf(outstr+strlen(outstr), "Failure"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Failure"); + break; + default: +- sprintf(outstr+strlen(outstr), "Unknown type"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Unknown type"); + break; + } + break; + default: // unknown +- sprintf(outstr+strlen(outstr), "Unknown type"); ++ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Unknown type"); + break; + } + diff --git a/util/wanpipemon/fe_lib.c b/util/wanpipemon/fe_lib.c index 5c6fa69..b0264f6 100644 --- a/util/wanpipemon/fe_lib.c +++ b/util/wanpipemon/fe_lib.c @@ -829,7 +829,8 @@ static void hw_set_lb_modes(unsigned char type, unsigned char mode) printf("Failed to %s line loopback mode.\n", (mode == WAN_TE1_ACTIVATE_LB) ? "activate" : "deactivate"); }else{ - printf("Line loopback mode is %s!\n", + printf("%s mode is %s!\n", + WAN_TE1_LB_TYPE_DECODE(type), (mode == WAN_TE1_ACTIVATE_LB) ? "activated" : "deactivated"); } return; @@ -884,8 +885,9 @@ void read_te1_56k_stat(int force) WAN_TE_YEL_ALARM(fe_stats->alarms), WAN_TE_OOF_ALARM(fe_stats->alarms)); }else{ - printf("OOF:\t%s\n", - WAN_TE_OOF_ALARM(fe_stats->alarms)); + printf("OOF:\t%s\t| RAI:\t%s\n", + WAN_TE_OOF_ALARM(fe_stats->alarms), + WAN_TE_RAI_ALARM(fe_stats->alarms)); } if (fe_stats->liu_alarms & WAN_TE_BIT_LIU_ALARM){