Checkin of wanpipe-2.3.2-7.tgz
This commit is contained in:
commit
328a4d6c83
|
@ -0,0 +1,358 @@
|
|||
# ============================================================================
|
||||
# Filelist WANPIPE WAN Router Distribution List
|
||||
#
|
||||
# copyright (c) 1996-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.
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# This is automatically generated file extracted from Prodlist
|
||||
#
|
||||
# Date: Wed Apr 9 20:42:28 EDT 2003
|
||||
|
||||
d wanpipe/doc 755 root root
|
||||
d wanpipe/patches 755 root root
|
||||
d wanpipe/patches/kdrivers 755 root root
|
||||
d wanpipe/patches/kdrivers/include 755 root root
|
||||
d wanpipe/patches/kdrivers/src 755 root root
|
||||
d wanpipe/patches/kdrivers/src/net 755 root root
|
||||
d wanpipe/patches/kdrivers/src/wanrouter 755 root root
|
||||
d wanpipe/samples 755 root root
|
||||
d wanpipe/util/misc 755 root root
|
||||
d wanpipe/util/misc/bin 755 root root
|
||||
d wanpipe/util/wanconfig 755 root root
|
||||
d wanpipe/util/wanconfig/lib 755 root root
|
||||
d wanpipe/util/wanpipemon 755 root root
|
||||
d wanpipe/util/sdladump 755 root root
|
||||
d wanpipe/util/ft1 755 root root
|
||||
d wanpipe/util/wancfg 755 root root
|
||||
d wanpipe/util/wancfg/lib 755 root root
|
||||
d wanpipe/util/lxdialog 755 root root
|
||||
d wanpipe/firmware 755 root root
|
||||
d wanpipe/interfaces 755 root root
|
||||
d wanpipe/api 755 root root
|
||||
d wanpipe/api/x25 755 root root
|
||||
d wanpipe/api/x25/pthread 755 root root
|
||||
d wanpipe/api/chdlc 755 root root
|
||||
d wanpipe/api/fr 755 root root
|
||||
d wanpipe/api/bitstrm 755 root root
|
||||
d wanpipe/api/bitstrm/te1 755 root root
|
||||
d wanpipe/api/bitstrm/te1/test_file 755 root root
|
||||
d wanpipe/api/bitstrm/datascope 755 root root
|
||||
d wanpipe/api/bisync 755 root root
|
||||
d wanpipe/api/bisync_strm 755 root root
|
||||
d wanpipe/api/sdlc 755 root root
|
||||
d wanpipe/api/pos 755 root root
|
||||
d wanpipe/api/lib 755 root root
|
||||
d wanpipe/snmp 755 root root
|
||||
d wanpipe/snmp/rfc 755 root root
|
||||
d wanpipe/rpmspec 755 root root
|
||||
f wanpipe/util/misc/wanpipe_setup 755 root root
|
||||
f wanpipe/Setup 755 root root
|
||||
f wanpipe/Filelist 644 root root
|
||||
f wanpipe/README 644 root root
|
||||
f wanpipe/README.changes 644 root root
|
||||
f wanpipe/README-1.install 644 root root
|
||||
f wanpipe/README-2.config 644 root root
|
||||
f wanpipe/README-3.operation 644 root root
|
||||
f wanpipe/README-4.debugging 644 root root
|
||||
f wanpipe/COPYING 644 root root
|
||||
f wanpipe/doc/README-1.install 644 root root
|
||||
f wanpipe/doc/README-2.config 644 root root
|
||||
f wanpipe/doc/README-3.operation 644 root root
|
||||
f wanpipe/doc/README-4.debugging 644 root root
|
||||
f wanpipe/doc/README.adsl 644 root root
|
||||
f wanpipe/doc/README.atm 644 root root
|
||||
f wanpipe/doc/README.bitstrm 644 root root
|
||||
f wanpipe/doc/README.ethernet_bridge 644 root root
|
||||
f wanpipe/doc/README.faq 644 root root
|
||||
f wanpipe/doc/README.irq_to_cpu_smp_mapping 644 root root
|
||||
f wanpipe/doc/README.loadbalancing 644 root root
|
||||
f wanpipe/doc/README.multilink 644 root root
|
||||
f wanpipe/doc/README.pppd 644 root root
|
||||
f wanpipe/doc/README.rpm 644 root root
|
||||
f wanpipe/doc/README.rpmbuild 644 root root
|
||||
f wanpipe/doc/README.wpbackupd 644 root root
|
||||
f wanpipe/doc/README.wpkbdmon 644 root root
|
||||
f wanpipe/doc/README.zebra_problems 644 root root
|
||||
f wanpipe/doc/README.pos 644 root root
|
||||
f wanpipe/doc/README.bitstrm 644 root root
|
||||
f wanpipe/doc/README.x25api 644 root root
|
||||
f wanpipe/doc/WanpipeInstallation.pdf 644 root root
|
||||
f wanpipe/doc/WanpipeConfiguration.pdf 644 root root
|
||||
f wanpipe/doc/WanpipeOperation.pdf 644 root root
|
||||
f wanpipe/doc/WanpipeDebugging.pdf 644 root root
|
||||
f wanpipe/doc/WanpipeEthernetBridge.pdf 644 root root
|
||||
f wanpipe/doc/x25_programming_manual.pdf 644 root root
|
||||
f wanpipe/doc/x25_firmware_api.pdf 644 root root
|
||||
f wanpipe/doc/Bisync.pdf 644 root root
|
||||
f wanpipe/doc/pos_api.pdf 644 root root
|
||||
f wanpipe/doc/bitstrm.pdf 644 root root
|
||||
f wanpipe/samples/README 644 root root
|
||||
f wanpipe/samples/wanpipe1.adsl 644 root root
|
||||
f wanpipe/samples/wanpipe1.atm 644 root root
|
||||
f wanpipe/samples/wanpipe1.asy 644 root root
|
||||
f wanpipe/samples/wanpipe1.atty 644 root root
|
||||
f wanpipe/samples/wanpipe1.bitstrm 644 root root
|
||||
f wanpipe/samples/wanpipe1.chdlc 644 root root
|
||||
f wanpipe/samples/wanpipe1.chdlc_t1 644 root root
|
||||
f wanpipe/samples/wanpipe1.fr 644 root root
|
||||
f wanpipe/samples/wanpipe1.fr_t1 644 root root
|
||||
f wanpipe/samples/wanpipe1.mult_fr 644 root root
|
||||
f wanpipe/samples/wanpipe1.mult_fr_t1 644 root root
|
||||
f wanpipe/samples/wanpipe1.mult_ppp_chdlc 644 root root
|
||||
f wanpipe/samples/wanpipe1.mult_ppp_chdlc_t1 644 root root
|
||||
f wanpipe/samples/wanpipe1.ppp 644 root root
|
||||
f wanpipe/samples/wanpipe1.ppp_t1 644 root root
|
||||
f wanpipe/samples/wanpipe1.sdlc 644 root root
|
||||
f wanpipe/samples/wanpipe1.stty 644 root root
|
||||
f wanpipe/samples/wanpipe1.x25 644 root root
|
||||
f wanpipe/samples/wanpipe1.pos 644 root root
|
||||
f wanpipe/samples/interface 644 root root
|
||||
f wanpipe/samples/wanrouter 644 root root
|
||||
f wanpipe/samples/redialer 644 root root
|
||||
f wanpipe/util/wanconfig/Makefile 644 root root
|
||||
f wanpipe/util/wanconfig/wanconfig.c 644 root root
|
||||
f wanpipe/util/wanconfig/lib/safe-read.c 644 root root
|
||||
f wanpipe/util/wanconfig/lib/safe-read.h 644 root root
|
||||
f wanpipe/util/sdladump/Makefile 644 root root
|
||||
f wanpipe/util/sdladump/sdladump.c 644 root root
|
||||
f wanpipe/util/wanpipemon/Makefile 644 root root
|
||||
f wanpipe/util/wanpipemon/fpipemon.c 644 root root
|
||||
f wanpipe/util/wanpipemon/prot_trace.c 644 root root
|
||||
f wanpipe/util/wanpipemon/cpipemon.c 644 root root
|
||||
f wanpipe/util/wanpipemon/bpipemon.c 644 root root
|
||||
f wanpipe/util/wanpipemon/ppipemon.c 644 root root
|
||||
f wanpipe/util/wanpipemon/xpipemon.c 644 root root
|
||||
f wanpipe/util/wanpipemon/fe_lib.c 644 root root
|
||||
f wanpipe/util/wanpipemon/fe_lib.h 644 root root
|
||||
f wanpipe/util/wanpipemon/docommand.c 644 root root
|
||||
f wanpipe/util/wanpipemon/wanpipemon.c 644 root root
|
||||
f wanpipe/util/wanpipemon/wangui.c 644 root root
|
||||
f wanpipe/util/wanpipemon/wanpipemon.h 644 root root
|
||||
f wanpipe/util/wanpipemon/xml_lib.c 644 root root
|
||||
f wanpipe/util/wanpipemon/dslpipemon.c 644 root root
|
||||
f wanpipe/util/wanpipemon/atmpipemon.c 644 root root
|
||||
f wanpipe/util/misc/Makefile 644 root root
|
||||
f wanpipe/util/misc/wpkbdmon.c 644 root root
|
||||
f wanpipe/util/misc/wanconfig_client.c 644 root root
|
||||
f wanpipe/util/misc/wp_x25_event_read.c 644 root root
|
||||
f wanpipe/patches/wanrouter-v2213.gz 644 root root
|
||||
f wanpipe/patches/wanrouter-v2214.gz 644 root root
|
||||
f wanpipe/patches/wanrouter-v2215.gz 644 root root
|
||||
f wanpipe/patches/wanrouter-v2218.gz 644 root root
|
||||
f wanpipe/patches/wanrouter-v2219.gz 644 root root
|
||||
f wanpipe/patches/wanrouter-v240.gz 644 root root
|
||||
f wanpipe/patches/wanrouter-v244.gz 644 root root
|
||||
f wanpipe/patches/wanrouter-v249.gz 644 root root
|
||||
f wanpipe/patches/wanrouter-v2416.gz 644 root root
|
||||
f wanpipe/patches/makefile.patch.2.2.X 644 root root
|
||||
f wanpipe/patches/makefile.patch.2.4.0 644 root root
|
||||
f wanpipe/patches/makefile.patch.2.4.4 644 root root
|
||||
f wanpipe/patches/makefile.af_wanpipe.patch 644 root root
|
||||
f wanpipe/patches/makefile.patch.utils.2.4.X 644 root root
|
||||
f wanpipe/patches/makefile.patch.utils.2.2.X 644 root root
|
||||
f wanpipe/patches/Fix_below_2211.gz 644 root root
|
||||
f wanpipe/patches/kdrivers/include/if_wanpipe.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/if_wanpipe_common.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_asy.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_bstrm.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_chdlc.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_fr.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_hdlc.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_ppp.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_x25.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdladrv.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdlapci.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdlasfm.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sfmdef.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanrouter.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanproc.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_bitstrm.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_edu.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_bscmp.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_snmp.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_bscstrm.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_mp_fr.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_sdlc.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_syncppp.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_kernel.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_version.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_te1.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_te1_def.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_56k.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_front_end.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_debug.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_defines.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_common.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_includes.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_cfg.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_pos.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_abstr.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_atm.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/wanpipe_atm_iface.h 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_chdlc.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_fr.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_ft1.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_ppp.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_x25.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdladrv.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdlamain.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_utils.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_multppp.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_syncppp.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_mp_fr.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_te1.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_56k.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_bitstrm.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_edu.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_bsc.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_bscstrm.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_sdlc.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_pos.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_abstr.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/wanrouter/wanmain.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/wanrouter/wanproc.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/wanrouter/waniface.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/wanrouter/af_wanpipe.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/wanrouter/af_wanpipe_datascope.c 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_adsl.h 644 root root
|
||||
f wanpipe/patches/kdrivers/include/sdla_adsl_iface.h 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_adsl.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_adsl_tty.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/sdla_atm.c 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_adsl.gcc2.i686.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_adsl.gcc2.i586.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_adsl.gcc2.i486.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_adsl.gcc2.i386.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_adsl.gcc3.i686.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_adsl.gcc3.i586.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_adsl.gcc3.i486.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_adsl.gcc3.i386.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_atm.gcc2.i686.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_atm.gcc2.i586.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_atm.gcc2.i486.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_atm.gcc2.i386.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_atm.gcc3.i686.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_atm.gcc3.i586.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_atm.gcc3.i486.o 644 root root
|
||||
f wanpipe/patches/kdrivers/src/net/wanpipe_atm.gcc3.i386.o 644 root root
|
||||
f wanpipe/firmware/fr514.sfm 644 root root
|
||||
f wanpipe/firmware/cdual514.sfm 644 root root
|
||||
f wanpipe/firmware/ppp514.sfm 644 root root
|
||||
f wanpipe/firmware/x25_514.sfm 644 root root
|
||||
f wanpipe/firmware/bitstrm.sfm 644 root root
|
||||
f wanpipe/firmware/edu_kit.sfm 644 root root
|
||||
f wanpipe/firmware/bscmp514.sfm 644 root root
|
||||
f wanpipe/firmware/bscstrm514.sfm 644 root root
|
||||
f wanpipe/firmware/sdlc514.sfm 644 root root
|
||||
f wanpipe/firmware/pos4680.sfm 644 root root
|
||||
f wanpipe/firmware/pos1255.sfm 644 root root
|
||||
f wanpipe/firmware/pos2126.sfm 644 root root
|
||||
f wanpipe/firmware/pos7000.sfm 644 root root
|
||||
f wanpipe/firmware/pos2127.sfm 644 root root
|
||||
f wanpipe/firmware/posicl.sfm 644 root root
|
||||
f wanpipe/firmware/atm514.sfm 644 root root
|
||||
f wanpipe/util/Makefile 644 root root
|
||||
f wanpipe/util/README 644 root root
|
||||
f wanpipe/util/ft1/Makefile 644 root root
|
||||
f wanpipe/util/ft1/README 644 root root
|
||||
f wanpipe/util/ft1/wanpipe_cfgft1 755 root root
|
||||
f wanpipe/util/ft1/Makefile 644 root root
|
||||
f wanpipe/util/ft1/ft1_config.c 644 root root
|
||||
f wanpipe/util/ft1/unixio.c 644 root root
|
||||
f wanpipe/util/ft1/unixio.h 644 root root
|
||||
f wanpipe/util/wancfg/Makefile 644 root root
|
||||
f wanpipe/util/wancfg/wancfg 755 root root
|
||||
f wanpipe/util/wancfg/pppconfig 755 root root
|
||||
f wanpipe/util/wancfg/README 644 root root
|
||||
f wanpipe/util/wancfg/lib/chdlc_lib.sh 644 root root
|
||||
f wanpipe/util/wancfg/lib/fr_lib.sh 644 root root
|
||||
f wanpipe/util/wancfg/lib/help.sh 644 root root
|
||||
f wanpipe/util/wancfg/lib/lib.sh 644 root root
|
||||
f wanpipe/util/wancfg/lib/ppp_lib.sh 644 root root
|
||||
f wanpipe/util/wancfg/lib/x25_lib.sh 644 root root
|
||||
f wanpipe/util/wancfg/lib/ss7_lib.sh 644 root root
|
||||
f wanpipe/util/wancfg/lib/adsl_lib.sh 644 root root
|
||||
f wanpipe/util/wancfg/lib/annexg_lib.sh 644 root root
|
||||
f wanpipe/util/wancfg/lib/atm_lib.sh 644 root root
|
||||
f wanpipe/util/lxdialog/Makefile 644 root root
|
||||
f wanpipe/util/lxdialog/checklist.c 644 root root
|
||||
f wanpipe/util/lxdialog/colors.h 644 root root
|
||||
f wanpipe/util/lxdialog/dialog.h 644 root root
|
||||
f wanpipe/util/lxdialog/inputbox.c 644 root root
|
||||
f wanpipe/util/lxdialog/lxdialog.c 644 root root
|
||||
f wanpipe/util/lxdialog/menu_text.c 644 root root
|
||||
f wanpipe/util/lxdialog/menubox.c 644 root root
|
||||
f wanpipe/util/lxdialog/menubox_back.c 644 root root
|
||||
f wanpipe/util/lxdialog/msgbox.c 644 root root
|
||||
f wanpipe/util/lxdialog/text_yesno.c 644 root root
|
||||
f wanpipe/util/lxdialog/textbox.c 644 root root
|
||||
f wanpipe/util/lxdialog/util.c 644 root root
|
||||
f wanpipe/util/lxdialog/yesno.c 644 root root
|
||||
f wanpipe/api/Makefile 644 root root
|
||||
f wanpipe/api/README 644 root root
|
||||
f wanpipe/api/x25/Makefile 644 root root
|
||||
f wanpipe/api/x25/README 644 root root
|
||||
f wanpipe/api/x25/server_v1.c 644 root root
|
||||
f wanpipe/api/x25/server_v2.c 644 root root
|
||||
f wanpipe/api/x25/svc_client.c 644 root root
|
||||
f wanpipe/api/x25/debug.c 644 root root
|
||||
f wanpipe/api/x25/pvc_client.c 644 root root
|
||||
f wanpipe/api/x25/hdlc_client.c 644 root root
|
||||
f wanpipe/api/x25/pthread/Makefile 644 root root
|
||||
f wanpipe/api/x25/pthread/bitmap.c 644 root root
|
||||
f wanpipe/api/x25/pthread/bitmap.h 644 root root
|
||||
f wanpipe/api/x25/pthread/server.c 644 root root
|
||||
f wanpipe/api/x25/pthread/server.h 644 root root
|
||||
f wanpipe/api/chdlc/Makefile 644 root root
|
||||
f wanpipe/api/chdlc/README 644 root root
|
||||
f wanpipe/api/chdlc/chdlc_api.c 644 root root
|
||||
f wanpipe/api/chdlc/chdlc_rts_cts.c 644 root root
|
||||
f wanpipe/api/fr/Makefile 644 root root
|
||||
f wanpipe/api/fr/README 644 root root
|
||||
f wanpipe/api/fr/fr_api.c 644 root root
|
||||
f wanpipe/api/bitstrm/Makefile 644 root root
|
||||
f wanpipe/api/bitstrm/bitstrm_api.c 644 root root
|
||||
f wanpipe/api/bitstrm/datascope/Makefile 644 root root
|
||||
f wanpipe/api/bitstrm/datascope/ss7_monitor_api.c 644 root root
|
||||
f wanpipe/api/bitstrm/te1/Makefile 644 root root
|
||||
f wanpipe/api/bitstrm/te1/bstrm_file_client.c 644 root root
|
||||
f wanpipe/api/bitstrm/te1/bstrm_file_server.c 644 root root
|
||||
f wanpipe/api/bitstrm/te1/bstrm_gen_file.c 644 root root
|
||||
f wanpipe/api/lib/lib_api.c 644 root root
|
||||
f wanpipe/api/lib/lib_api.h 644 root root
|
||||
f wanpipe/api/bisync/Makefile 644 root root
|
||||
f wanpipe/api/bisync/README 644 root root
|
||||
f wanpipe/api/bisync/bsc_cmd.c 644 root root
|
||||
f wanpipe/api/bisync/bsc_api.c 644 root root
|
||||
f wanpipe/api/bisync_strm/Makefile 644 root root
|
||||
f wanpipe/api/bisync_strm/README 644 root root
|
||||
f wanpipe/api/bisync_strm/bscstrm_api.c 644 root root
|
||||
f wanpipe/api/sdlc/Makefile 644 root root
|
||||
f wanpipe/api/sdlc/README 644 root root
|
||||
f wanpipe/api/sdlc/sdlc_api.c 644 root root
|
||||
f wanpipe/api/pos/Makefile 644 root root
|
||||
f wanpipe/api/pos/pos_api.pdf 644 root root
|
||||
f wanpipe/api/pos/pos_api.c 644 root root
|
||||
f wanpipe/rpmspec/wanpipe.spec 644 root root
|
||||
f wanpipe/rpmspec/wanpipe-mod.spec 644 root root
|
||||
f wanpipe/rpmspec/wanpipe-util.spec 644 root root
|
||||
f wanpipe/snmp/README 644 root root
|
||||
f wanpipe/snmp/frameRelayDTE.c 644 root root
|
||||
f wanpipe/snmp/frameRelayDTE.h 644 root root
|
||||
f wanpipe/snmp/ppp.c 644 root root
|
||||
f wanpipe/snmp/ppp.h 644 root root
|
||||
f wanpipe/snmp/x25.c 644 root root
|
||||
f wanpipe/snmp/x25.h 644 root root
|
||||
f wanpipe/snmp/rfc/rfc1315.txt 644 root root
|
||||
f wanpipe/snmp/rfc/rfc1471.txt 644 root root
|
||||
f wanpipe/snmp/rfc/rfc1473.txt 644 root root
|
||||
f wanpipe/snmp/rfc/rfc2495.txt 644 root root
|
||||
f wanpipe/snmp/rfc/rfc1382.txt 644 root root
|
||||
f wanpipe/snmp/rfc/rfc1472.txt 644 root root
|
||||
f wanpipe/snmp/rfc/rfc1474.txt 644 root root
|
|
@ -0,0 +1,351 @@
|
|||
# ============================================================================
|
||||
# Makefile Multiprotocol WAN Router for Linux. Make Script.
|
||||
#
|
||||
# Copyright (c) 1995-1997 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Mar 27 2000 Nenad Corbic Version 2.0.5 to 2.1.2
|
||||
# Jan 07, 1999 Jaspreet Singh Version 2.0.4
|
||||
# Aug 25, 1998 Jaspreet Singh Version 2.0.3
|
||||
# Nov 06, 1997 Jaspreet Singh Version 2.0.0
|
||||
# Jul 28, 1997 Jaspreet Singh Version 1.0.5
|
||||
# Jul 10, 1997 Jaspreet Singh Version 1.0.4
|
||||
# June 3, 1997 Jaspreet Singh Version 1.0.3
|
||||
# Jan 15, 1997 Gene Kozin Version 1.0.1.
|
||||
# Dec 31, 1996 Gene Kozin Initial version.
|
||||
# ============================================================================
|
||||
|
||||
####### DEFINES ##############################################################
|
||||
|
||||
# Build Options.
|
||||
PROD = wanrouter
|
||||
VERSION = 2.3.0
|
||||
DEBUG = 2
|
||||
OS_TYPE =__LINUX__
|
||||
WANPIPE_TDM_VOICE = YES
|
||||
WANPIPE_ADSL = NO
|
||||
WANPIPE_ATM = NO
|
||||
KERNEL_HDLC_ENABLED=NO
|
||||
|
||||
# Project File Paths.
|
||||
TMPDIR = tmp
|
||||
OUTDIR = mod
|
||||
LOCINC = /usr/src/linux/include
|
||||
VPATH = $(LOCINC):$(TMPDIR)
|
||||
ARCH = $(shell uname -m)
|
||||
ANNEXG_INC=../include/annexg
|
||||
ADSLDIR = ../adsl
|
||||
|
||||
MODDIR=modinfo
|
||||
|
||||
TARGETS = $(OUTDIR)/wanrouter.o \
|
||||
$(OUTDIR)/sdladrv.o \
|
||||
$(OUTDIR)/wanpipe.o \
|
||||
$(OUTDIR)/wanpipe_syncppp.o
|
||||
|
||||
#KERN := $(shell uname -r | grep 2.4)
|
||||
KERN := $(shell grep 2.4 /usr/src/linux/include/linux/version.h)
|
||||
KERN_V26 := $(shell grep 2.6 /usr/src/linux/include/linux/version.h)
|
||||
LD_ELF=
|
||||
|
||||
PRODUCT_DEFINES= -DCONFIG_PRODUCT_WANPIPE_BASE -DCONFIG_PRODUCT_WANPIPE_BITSTRM -DSS7_USER_ID=0x00 -DCONFIG_PRODUCT_WANPIPE_SDLC -DCONFIG_PRODUCT_WANPIPE_EDU -DCONFIG_PRODUCT_WANPIPE_POS -DCONFIG_PRODUCT_WANPIPE_FR -DCONFIG_PRODUCT_WANPIPE_CHDLC -DCONFIG_PRODUCT_WANPIPE_PPP -DCONFIG_PRODUCT_WANPIPE_MULTPROT -DCONFIG_PRODUCT_WANPIPE_MULTFR -DCONFIG_PRODUCT_WANPIPE_X25 -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_TE1 -DCONFIG_PRODUCT_WANPIPE_AFT_TE3 -DCONFIG_PRODUCT_WANPIPE_ADCCP
|
||||
|
||||
ifeq "${WANPIPE_ADSL}" "YES"
|
||||
PRODUCT_DEFINES+= -DCONFIG_PRODUCT_WANPIPE_ADSL
|
||||
endif
|
||||
|
||||
ifeq "${WANPIPE_ATM}" "YES"
|
||||
PRODUCT_DEFINES+= -DCONFIG_PRODUCT_WANPIPE_ATM
|
||||
endif
|
||||
|
||||
|
||||
ifeq "${WANPIPE_TDM_VOICE}" "YES"
|
||||
PRODUCT_DEFINES+= -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE
|
||||
endif
|
||||
|
||||
ifeq "${KERNEL_HDLC_ENABLED}" "YES"
|
||||
PRODUCT_DEFINES+= -DCONFIG_PRODUCT_WANPIPE_GENERIC
|
||||
endif
|
||||
|
||||
ifneq "${KERN}" ""
|
||||
|
||||
#Found 2.4 Kernel
|
||||
|
||||
MODTYPE=o
|
||||
K_WAN_DIR=drivers/net/wan
|
||||
|
||||
CFLAGS=-D__KERNEL__ -D$(OS_TYPE) $(PRODUCT_DEFINES) -I$(ANNEXG_INC) -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -mpreferred-stack-boundary=2 -march=$(ARCH) -DMODULE -DEXPORT_SYMTAB
|
||||
|
||||
|
||||
WANPIPE_FILE_LIST= sdlamain.o sdla_fr.o sdla_ppp.o sdla_chdlc.o sdla_x25.o sdla_ft1.o wanpipe_multppp.o sdla_te1.o sdla_56k.o sdla_xilinx.o sdla_aft_te1.o sdla_aft_te3.o sdla_te3.o wanpipe_utils.o wanpipe_abstr.o wanpipe_linux_iface.o
|
||||
|
||||
ifeq "${WANPIPE_ADSL}" "YES"
|
||||
WANPIPE_FILE_LIST+= sdla_adsl.o ../adsl/wanpipe_adsl.o
|
||||
endif
|
||||
|
||||
ifeq "${WANPIPE_ATM}" "YES"
|
||||
WANPIPE_FILE_LIST+= sdla_atm.o ../atm/wanpipe_atm.o
|
||||
endif
|
||||
|
||||
ifeq "${WANPIPE_TDM_VOICE}" "YES"
|
||||
WANPIPE_FILE_LIST+= sdla_tdmv.o
|
||||
CFLAGS+=-I/usr/src/zaptel
|
||||
endif
|
||||
|
||||
|
||||
else
|
||||
|
||||
ifneq "${KERN_V26}" ""
|
||||
|
||||
#Found 2.6 Kernel
|
||||
LD_ELF=-m elf_i386
|
||||
|
||||
MODTYPE=ko
|
||||
K_WAN_DIR=drivers/net/wan
|
||||
|
||||
CFLAGS=-Wp,-MD,.wanpipe.o.d -nostdinc -iwithprefix include -D__KERNEL__ -D$(OS_TYPE) $(PRODUCT_DEFINES) -I$(ANNEXG_INC) -I/usr/src/linux/include -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -msoft-float -march=$(ARCH) -I/usr/src/linux/include/asm-i386/mach-default -O2 -DMODULE
|
||||
|
||||
WANPIPE_FILE_LIST= sdlamain.o sdla_fr.o sdla_ppp.o sdla_chdlc.o sdla_x25.o sdla_ft1.o wanpipe_multppp.o sdla_te1.o sdla_56k.o sdla_xilinx.o sdla_aft_te1.o sdla_aft_te3.o sdla_te3.o wanpipe_utils.o wanpipe_abstr.o wanpipe_linux_iface.o
|
||||
|
||||
endif
|
||||
|
||||
ifeq "${WANPIPE_ADSL}" "NO"
|
||||
WANPIPE_FILE_LIST+= sdla_adsl.o ../adsl/wanpipe_adsl.o
|
||||
endif
|
||||
|
||||
ifeq "${WANPIPE_ATM}" "NO"
|
||||
WANPIPE_FILE_LIST+= sdla_atm.o ../atm/wanpipe_atm.o
|
||||
endif
|
||||
|
||||
ifeq "${WANPIPE_TDM_VOICE}" "YES"
|
||||
WANPIPE_FILE_LIST+= sdla_tdmv.o
|
||||
CFLAGS+=-I/usr/src/zaptel
|
||||
endif
|
||||
|
||||
|
||||
|
||||
TARGETS = $(OUTDIR)/wanrouter.ko \
|
||||
$(OUTDIR)/sdladrv.ko \
|
||||
$(OUTDIR)/wanpipe.ko \
|
||||
$(OUTDIR)/wanpipe_syncppp.ko
|
||||
|
||||
endif
|
||||
|
||||
|
||||
# Miscellaneous.
|
||||
TAGFILE = net/wanrouter/patchlevel
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
|
||||
all: $(TARGETS)
|
||||
@echo "Ok."
|
||||
|
||||
$(OUTDIR)/wanrouter.ko: $(OUTDIR)/wanrouter.o $(MODDIR)/wanrouter.mod.o
|
||||
ld $(LD_ELF) -r -o $@ $^
|
||||
chmod 664 $@
|
||||
|
||||
$(OUTDIR)/sdladrv.ko: $(OUTDIR)/sdladrv.o $(MODDIR)/sdladrv.mod.o
|
||||
ld $(LD_ELF) -r -o $@ $^
|
||||
chmod 664 $@
|
||||
|
||||
$(OUTDIR)/wanpipe.ko: $(OUTDIR)/wanpipe.o $(MODDIR)/wanpipe.mod.o
|
||||
ld $(LD_ELF) -r -o $@ $^
|
||||
chmod 664 $@
|
||||
|
||||
$(OUTDIR)/wanpipe_syncppp.ko: $(OUTDIR)/wanpipe_syncppp.o $(MODDIR)/wanpipe_syncppp.mod.o
|
||||
ld $(LD_ELF) -r -o $@ $^
|
||||
chmod 664 $@
|
||||
|
||||
|
||||
$(MODDIR)/wanrouter.mod.o: $(MODDIR)/wanrouter.mod.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=wanrouter -DKBUILD_MODNAME=wanrouter -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(MODDIR)/sdladrv.mod.o: $(MODDIR)/sdladrv.mod.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdladrv -DKBUILD_MODNAME=sdladrv -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(MODDIR)/wanpipe.mod.o: $(MODDIR)/wanpipe.mod.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=wanpipe -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(MODDIR)/wanpipe_syncppp.mod.o: $(MODDIR)/wanpipe_syncppp.mod.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=wanpipe_syncppp -DKBUILD_MODNAME=wanpipe_syncppp -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
|
||||
|
||||
|
||||
# ----- Multiprotocol WAN router module --------------------------------------
|
||||
|
||||
$(OUTDIR)/wanrouter.o: wanmain.o wanproc.o waniface.o
|
||||
ld $(LD_ELF) -r -o $@ $^
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/wanmain.o: wanmain.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=wanmain -DKBUILD_MODNAME=wanrouter -c -o $@ $<
|
||||
|
||||
$(TMPDIR)/wanproc.o: common/wanproc.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=wanproc -DKBUILD_MODNAME=wanrouter -c -o $@ $<
|
||||
|
||||
$(TMPDIR)/waniface.o: waniface.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=waniface -DKBUILD_MODNAME=wanrouter -c -o $@ $<
|
||||
|
||||
# ----- SDLA Support Module --------------------------------------------------
|
||||
|
||||
|
||||
$(OUTDIR)/sdladrv.o: common/sdladrv.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdladrv -DKBUILD_MODNAME=sdladrv -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(OUTDIR)/wanpipe_syncppp.o: wanpipe_syncppp.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=wanpipe_syncppp -DKBUILD_MODNAME=wanpipe_syncppp -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
# ----- WANPIPE(tm) Driver Module --------------------------------------------
|
||||
|
||||
$(OUTDIR)/wanpipe.o: ${WANPIPE_FILE_LIST}
|
||||
ld $(LD_ELF) -r -o $@ $^
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdlamain.o: sdlamain.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdlamain -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_x25.o: sdla_x25.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_x25 -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_fr.o: sdla_fr.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_fr -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_ppp.o: sdla_ppp.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_ppp -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_chdlc.o: sdla_chdlc.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_chdlc -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_ft1.o: sdla_ft1.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_ft1 -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/wanpipe_multppp.o: wanpipe_multppp.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=wanpipe_multppp -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_te1.o: common/sdla_te1.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_te1 -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_56k.o: common/sdla_56k.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_56k -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_bitstrm.o: sdla_bitstrm.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_bitstrm -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_edu.o: sdla_edu.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_edu -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_bsc.o: sdla_bsc.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_bsc -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_ss7.o: sdla_ss7.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_ss7 -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_bscstrm.o: sdla_bscstrm.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_bscstrm -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_mp_fr.o: sdla_mp_fr.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_mp_fr -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_sdlc.o: sdla_sdlc.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_sdlc -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_tdmv.o: common/sdla_tdmv.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_tdmv -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_atm.o: common/sdla_atm.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_atm -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_xilinx.o: common/sdla_xilinx.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_xilinx -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_aft_te1.o: common/sdla_aft_te1.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_aft_te1 -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_aft_te3.o: common/sdla_aft_te3.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_aft_te3 -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_aft_te1_ss7.o: common/sdla_aft_te1_ss7.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_aft_te1_ss7 -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_te3.o: common/sdla_te3.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_te3 -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_pos.o: common/sdla_pos.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_pos -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/wanpipe_utils.o: common/wanpipe_utils.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=wanpipe_utils -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/wanpipe_abstr.o: common/wanpipe_abstr.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=wanpipe_abstr -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_adsl.o: common/sdla_adsl.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_adsl -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/sdla_adccp.o: sdla_adccp.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=sdla_adccp -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
$(TMPDIR)/wanpipe_linux_iface.o: wanpipe_linux_iface.c
|
||||
$(CC) $(CFLAGS) -DKBUILD_BASENAME=wanpipe_linux_iface -DKBUILD_MODNAME=wanpipe -c -o $@ $<
|
||||
chmod 664 $@
|
||||
|
||||
clean:
|
||||
rm -f mod/*.*o
|
||||
rm -f tmp/*.*o
|
||||
rm -f modinfo/*.o
|
||||
rm -f *.o
|
||||
|
||||
ver:
|
||||
@echo "Building 2.4 = ${KERN}"
|
||||
@echo "Building 2.6 = ${KERN_V26}"
|
||||
|
||||
install:
|
||||
install -D $(OUTDIR)/wanrouter.${MODTYPE} /lib/modules/$(shell uname -r)/kernel/net/wanrouter/wanrouter.${MODTYPE}
|
||||
install -D $(OUTDIR)/sdladrv.${MODTYPE} /lib/modules/$(shell uname -r)/kernel/$(K_WAN_DIR)/sdladrv.${MODTYPE}
|
||||
install -D $(OUTDIR)/wanpipe_syncppp.${MODTYPE} /lib/modules/$(shell uname -r)/kernel/$(K_WAN_DIR)/wanpipe_syncppp.${MODTYPE}
|
||||
install -D $(OUTDIR)/wanpipe.${MODTYPE} /lib/modules/$(shell uname -r)/kernel/$(K_WAN_DIR)/wanpipe.${MODTYPE}
|
||||
|
||||
|
||||
uninstall:
|
||||
\rm -f /lib/modules/$(shell uname -r)/kernel/net/wanrouter/wanrouter.*
|
||||
\rm -f /lib/modules/$(shell uname -r)/kernel/$(K_WAN_DIR)/wanrouter.*
|
||||
\rm -f /lib/modules/$(shell uname -r)/kernel/$(K_WAN_DIR)/sdladrv.*
|
||||
\rm -f /lib/modules/$(shell uname -r)/kernel/$(K_WAN_DIR)/wanpipe_syncppp.*
|
||||
\rm -f /lib/modules/$(shell uname -r)/kernel/$(K_WAN_DIR)/wanpipe.*
|
||||
|
||||
###### END ###################################################################
|
|
@ -0,0 +1,685 @@
|
|||
------------------------------------------------------------------------------
|
||||
Linux WAN Router Utilities Package
|
||||
------------------------------------------------------------------------------
|
||||
Version 2.3.2-7
|
||||
Jan 5 2006
|
||||
Author: Nenad Corbic <ncorbic@sangoma.com>
|
||||
Copyright (c) 1995-2005 Sangoma Technologies Inc.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
INTRODUCTION
|
||||
|
||||
Wide Area Networks (WANs) are used to interconnect Local Area Networks (LANs)
|
||||
and/or stand-alone hosts over vast distances with data transfer rates
|
||||
significantly higher than those achievable with commonly used dial-up
|
||||
connections.
|
||||
|
||||
Usually an external device called `WAN router' sitting on your local network
|
||||
or connected to your machine's serial port provides physical connection to
|
||||
WAN. Although router's job may be as simple as taking your local network
|
||||
traffic, converting it to WAN format and piping it through the WAN link, these
|
||||
devices are notoriously expensive, with prices as much as 2 - 5 times higher
|
||||
then the price of a typical PC box.
|
||||
|
||||
Alternatively, considering robustness and multitasking capabilities of Linux,
|
||||
an internal router can be built (most routers use some sort of stripped down
|
||||
Unix-like operating system anyway). With a number of relatively inexpensive WAN
|
||||
interface cards available on the market, a perfectly usable router can be
|
||||
built for less than half a price of an external router. Yet a Linux box
|
||||
acting as a router can still be used for other purposes, such as fire-walling,
|
||||
running FTP, WWW or DNS server, etc.
|
||||
|
||||
This kernel module introduces the notion of a WAN Link Driver (WLD) to Linux
|
||||
operating system and provides generic hardware-independent services for such
|
||||
drivers. Why can existing Linux network device interface not be used for
|
||||
this purpose? Well, it can. However, there are a few key differences between
|
||||
a typical network interface (e.g. Ethernet) and a WAN link.
|
||||
|
||||
Many WAN protocols, such as X.25 and frame relay, allow for multiple logical
|
||||
connections (known as `virtual circuits' in X.25 terminology) over a single
|
||||
physical link. Each such virtual circuit may (and almost always does) lead
|
||||
to a different geographical location and, therefore, different network. As a
|
||||
result, it is the virtual circuit, not the physical link, that represents a
|
||||
route and, therefore, a network interface in Linux terms.
|
||||
|
||||
To further complicate things, virtual circuits are usually volatile in nature
|
||||
(excluding so called `permanent' virtual circuits or PVCs). With almost no
|
||||
time required to set up and tear down a virtual circuit, it is highly desirable
|
||||
to implement on-demand connections in order to minimize network charges. So
|
||||
unlike a typical network driver, the WAN driver must be able to handle multiple
|
||||
network interfaces and cope as multiple virtual circuits come into existence
|
||||
and go away dynamically.
|
||||
|
||||
Last, but not least, WAN configuration is much more complex than that of say
|
||||
Ethernet and may well amount to several dozens of parameters. Some of them
|
||||
are "link-wide" while others are virtual circuit-specific. The same holds
|
||||
true for WAN statistics which is by far more extensive and extremely useful
|
||||
when troubleshooting WAN connections. Extending the ifconfig utility to suit
|
||||
these needs may be possible, but does not seem quite reasonable. Therefore, a
|
||||
WAN configuration utility and corresponding application programmer's interface
|
||||
is needed for this purpose.
|
||||
|
||||
Most of these problems are taken care of by this module. Its goal is to
|
||||
provide a user with more-or-less standard look and feel for all WAN devices and
|
||||
assist a WAN device driver writer by providing common services, such as:
|
||||
|
||||
o User-level interface via /proc file system
|
||||
o Centralized configuration
|
||||
o Device management (setup, shutdown, etc.)
|
||||
o Network interface management (dynamic creation/destruction)
|
||||
o Protocol encapsulation/decapsulation
|
||||
|
||||
To ba able to use the Linux WAN Router you will also need a WAN Tools package
|
||||
available from
|
||||
|
||||
ftp.sangoma.com/pub/linux/current_wanpipe/wanpipe-X.Y.Z.tgz
|
||||
|
||||
where vX.Y.Z represent the wanpipe version number.
|
||||
|
||||
For technical questions and/or comments please e-mail to ncorbic@sangoma.com.
|
||||
For general inquiries please contact Sangoma Technologies Inc. by
|
||||
|
||||
Hotline: 1-800-388-2475 (USA and Canada, toll free)
|
||||
Phone: (905) 474-1990 ext: 106
|
||||
Fax: (905) 474-9223
|
||||
E-mail: dm@sangoma.com (David Mandelstam)
|
||||
ncorbic@sangoma.com (Nenad Corbic)
|
||||
WWW: http://www.sangoma.com
|
||||
|
||||
|
||||
INSTALLATION
|
||||
|
||||
Please read the README.install on how to
|
||||
install the WANPIPE tools and drivers properly.
|
||||
|
||||
|
||||
After installation read README.config on how
|
||||
to configure and start wanpipe device.
|
||||
|
||||
For further information refer to the
|
||||
doc/ directory.
|
||||
|
||||
ftp.sangoma.com/linux/current_wanpipe/doc
|
||||
|
||||
|
||||
COPYRIGHT AND LICENSING INFORMATION
|
||||
|
||||
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, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 675 Mass
|
||||
Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
|
||||
ACKNOWLEDGEMENTS
|
||||
|
||||
This product is based on the WANPIPE(tm) Multiprotocol WAN Router developed
|
||||
by Sangoma Technologies Inc. for Linux 2.0.x and 2.2.x. Success of the WANPIPE
|
||||
together with the next major release of Linux kernel in summer 1996 commanded
|
||||
adequate changes to the WANPIPE code to take full advantage of new Linux
|
||||
features.
|
||||
|
||||
Instead of continuing developing proprietary interface tied to Sangoma WAN
|
||||
cards, we decided to separate all hardware-independent code into a separate
|
||||
module and defined two levels of interfaces - one for user-level applications
|
||||
and another for kernel-level WAN drivers. WANPIPE is now implemented as a
|
||||
WAN driver compliant with the WAN Link Driver interface. Also a general
|
||||
purpose WAN configuration utility and a set of shell scripts was developed to
|
||||
support WAN router at the user level.
|
||||
|
||||
Many useful ideas concerning hardware-independent interface implementation
|
||||
were given by Mike McLagan <mike.mclagan@linux.org> and his implementation
|
||||
of the Frame Relay router and drivers for Sangoma cards (dlci/sdla).
|
||||
|
||||
With the new implementation of the APIs being incorporated into the WANPIPE,
|
||||
a special thank goes to Alan Cox in providing insight into BSD sockets.
|
||||
|
||||
Special thanks to all the WANPIPE users who performed field-testing, reported
|
||||
bugs and made valuable comments and suggestions that help us to improve this
|
||||
product.
|
||||
|
||||
o The 2.3.2 release contains:
|
||||
|
||||
Stable TDMV Wanpipe drivers for Asterisk.
|
||||
The TDMV drivers support both A102 and A104 cars.
|
||||
Please read wanpipe/doc/README.asterisk
|
||||
|
||||
Stable TE3 Drivers for AFT A301 TE3 Unchannelized Card.
|
||||
All WAN protocols are supported: Frame Relay, PPP, CHDLC..
|
||||
|
||||
Stable LIP Network Layer: Separates Wanpipe hardware from
|
||||
the Network Protocols: Frame Relay, CHDLC,
|
||||
PPP, LAPB API, XDLC API
|
||||
|
||||
o The 2.3.1 contains major structural driver changes.
|
||||
The new Hardware Abstraction layer cleanly separates, the
|
||||
physical layer from the driver/protocol layers.
|
||||
|
||||
Support for 2.6.X kernel.
|
||||
|
||||
o From 2.3.0 contains major structural driver changes
|
||||
most notably the ADSL OS abstraction layer. ADLS drivers
|
||||
can now be compiled against any custom kernel.
|
||||
|
||||
o From 2.2.6 release forward the new S514-7 Dual T/E1,
|
||||
S514-8 Single TE1 and S518 ADSL cards are supproted.
|
||||
|
||||
o From 2.2.4 release forward the new S514-4 T/E1 and S514-5 56K
|
||||
cards are supported.
|
||||
|
||||
o From 2.2.3 release forward ALL wanpipe modules
|
||||
including API modules, can be recompiled from
|
||||
./Setup installation script!
|
||||
NO KERNEL RECOMPILATION is necessary.
|
||||
|
||||
o From 2.2.3 release forward, wanpipe directory
|
||||
architecture has been changed. New home directory
|
||||
for wanpipe is /etc/wanpipe.
|
||||
|
||||
o All old releases are in ../old_releases/wanpipe directory.
|
||||
|
||||
o Custom RPMs can be build based on current kernel image
|
||||
by using the ./Setup buildrpm command.
|
||||
Read the README.rpmbuild.
|
||||
|
||||
|
||||
|
||||
NEW IN STABLE 2.3.2-7 RELEASE
|
||||
==============================
|
||||
2.3.2-7
|
||||
Jan 05 2005
|
||||
|
||||
o Allow CHDLC API to run in Non-Root mode
|
||||
o LIP over Async Mode
|
||||
o Bug fix in XDLC transmit code
|
||||
o New Setup Driver Build logic using 2.6 Kbuild make files
|
||||
|
||||
|
||||
2.3.2-6
|
||||
Sep 24 2005
|
||||
|
||||
o AFT A102 TDM Bug Fix
|
||||
The AFT A102 card could experience unpredicted
|
||||
behaviour on extermely noisy T1/E1 lines.
|
||||
This issue has now been fixed.
|
||||
|
||||
2.3.2-5
|
||||
Sep 12 2005
|
||||
|
||||
o AFT A101/2 Drivers E1 State Update
|
||||
Bug fix on displaying initial E1 state.
|
||||
The LED displayed green on inital E1
|
||||
start.
|
||||
|
||||
o AFT A101/2 Drivers Update
|
||||
The AFT A101/2 cards configured for LIP PPP
|
||||
segfaulted in some instances during shutdown.
|
||||
|
||||
|
||||
o AFT A301 T3 Driver Updated
|
||||
Tighter timeout conditions as well as
|
||||
bug fix in rx,tx error handling.
|
||||
|
||||
o New Wanpipe firmware update program.
|
||||
Option to auto update firmware on all
|
||||
AFT cards.
|
||||
./wanpipe/util/wan_aftup/update_aft_firm.sh -auto
|
||||
|
||||
|
||||
2.3.2-4
|
||||
Jun 14 2005
|
||||
|
||||
o Wanpipe PPP protocol
|
||||
Bug fix in ip negotiation code
|
||||
|
||||
o Updates to ./Setup installation script
|
||||
Added fixes for new distributions
|
||||
Wanpipe compilation will now work on
|
||||
partial linux HEADER source.
|
||||
Therefore, no full source is necessary.
|
||||
|
||||
o Driver updates for new 2.6.12 kernel
|
||||
Internals of the SOCKET API code.
|
||||
af_wanpipe.c
|
||||
|
||||
2.3.2-3
|
||||
May 06 2005
|
||||
|
||||
o A102 TDMV Driver Update
|
||||
The A102 Driver will now provide clocking to
|
||||
zaptel even if the front end is disconnected.
|
||||
|
||||
o A104 TDMV Driver
|
||||
The A104 Driver failed to unload properly if
|
||||
one tried to stop it before Asterisk.
|
||||
This has now been fixed :)
|
||||
|
||||
2.3.2-2
|
||||
Apr 28 2005
|
||||
|
||||
o Update to A102 Channelized Driver
|
||||
The bug affected the shutdown of last
|
||||
channelized interface. The last channelized
|
||||
interface brought down all other interfaces
|
||||
except the first one.
|
||||
|
||||
o Update to Bitstreaming driver
|
||||
Failed to compile on gcc 3.3.
|
||||
|
||||
o Updated Setup installation script.
|
||||
Setup will now catch common ZAPTEL
|
||||
misconfigurations.
|
||||
|
||||
2.3.2-1
|
||||
Apr 05 2005
|
||||
|
||||
Stable TDMV Wanpipe drivers for Asterisk.
|
||||
The TDMV drivers support both A102 and A104 cars.
|
||||
Please read wanpipe/doc/README.asterisk
|
||||
|
||||
Stable TE3 Drivers for AFT A301 TE3 Unchannelized Card.
|
||||
All WAN protocols are supported: Frame Relay, PPP, CHDLC..
|
||||
|
||||
Stable LIP Network Layer: Separates Wanpipe hardware from
|
||||
the Network Protocols: Frame Relay, CHDLC,
|
||||
PPP, LAPB API, XDLC API
|
||||
|
||||
|
||||
o 2.6 Kernel PCI Routing problem Fixed on S514 Cards
|
||||
The S514 Card failed to initialize routed
|
||||
irq.
|
||||
|
||||
o Minor bug fixes in statistic reporting
|
||||
AFT and ADSL drivers.
|
||||
|
||||
o New README.asterisk
|
||||
|
||||
|
||||
beta7-2.3.2
|
||||
Mar 16 2005
|
||||
|
||||
o AFT TDMV Update
|
||||
Added WINK support to TDMV driver.
|
||||
|
||||
o AFT TDMV Update
|
||||
Fixed up latecny issues with RBS signalling
|
||||
For A104 and A101/2 cards.
|
||||
|
||||
o AFT A104 and 101/2 drivers updates
|
||||
Added checks to prevent stopping wanpipe while
|
||||
Asterisk is running
|
||||
|
||||
o AFT A300 TE3 Update
|
||||
Fixed the link restart recovery.
|
||||
|
||||
o AFT A104 TE1 Configuration Update
|
||||
Update to the TE1 physical layer paramters
|
||||
|
||||
o AFT Firmware Update
|
||||
The firmware update utility was updated
|
||||
from the AFT300 TE3 card.
|
||||
|
||||
o AFT TE3 Driver Update
|
||||
Removed the chip security check
|
||||
|
||||
|
||||
beta6-2.3.2
|
||||
Feb 25 2005
|
||||
|
||||
o AFT A104 Drivers: TDMV Update
|
||||
|
||||
The A104 cards did not default to bit
|
||||
swapping in TDMV voice mode. This was
|
||||
a configuration option. This update configures
|
||||
the board for automatic bitswapping in
|
||||
hardware by default.
|
||||
|
||||
|
||||
beta5-2.3.2
|
||||
Feb 21 2005
|
||||
|
||||
|
||||
o AFT A104 Drivers
|
||||
Fixed the FIFO leveling so that single timeslot
|
||||
interfaces can operate properly
|
||||
(TDMV Voice Only)
|
||||
|
||||
o AFT Front End TE1 Update
|
||||
Synchronized fe timers and added checks
|
||||
to avoid adding an already pending timer.
|
||||
|
||||
o AFT A101/2 Driver update
|
||||
Fixed the 2 HDLC channel operation on
|
||||
unchannelized card.
|
||||
|
||||
Add support for Master clocking from
|
||||
a adjacent line, instead of the oscillator.
|
||||
Used by TDM_VOICE switching applications.
|
||||
Need: AFT A101/2 Firmware version V24
|
||||
|
||||
Fixed Synchronization issues with TDM VOICE
|
||||
Racing condition exists during driver startup.
|
||||
If the Front End comes up before interfaces
|
||||
come up, timeslot synchornization can go out
|
||||
of sync.
|
||||
|
||||
o New wan_aftup Utility
|
||||
Located wanpipe/util/wan_aftup
|
||||
|
||||
Used to update AFT firmware.
|
||||
|
||||
Please read the README file
|
||||
wanpipe/util/wan_aftup/README
|
||||
|
||||
|
||||
o LIP Update
|
||||
Updated Carrier loss recover on all LIP protocols.
|
||||
Frame Relay, PPP, CHDLC
|
||||
|
||||
o Updated LIP Frame Relay API
|
||||
Support for 1 byte reception
|
||||
|
||||
o Updated Hardware Probe
|
||||
Includes the distinction between Channalized and
|
||||
UnChannalized AFT cards.
|
||||
|
||||
|
||||
o TDMV Echo Update
|
||||
Improved echo canceling performance
|
||||
|
||||
o Wancfg
|
||||
Updated the TDMV parameters
|
||||
|
||||
o Wanpipe TE3 Driver Update
|
||||
Better front end recovery after
|
||||
a front end disconnect.
|
||||
|
||||
o Wanpipe LIP Frame Relay API update
|
||||
Wanpipe LIP debug messages removed
|
||||
|
||||
o Wanpipe hwprobe
|
||||
Distinction between Channalized and Unchannalized cards
|
||||
|
||||
o AFT Security Check
|
||||
Due to some bad pci busses, the chip security
|
||||
checking has been made more robust.
|
||||
|
||||
o TDMV Span Number Update
|
||||
|
||||
|
||||
|
||||
beta4-2.3.2
|
||||
Feb 04 2005
|
||||
|
||||
o Voice TDM BUG FIX
|
||||
|
||||
Both A104 and A101/2 card had a bug where
|
||||
on T1/E1 re-connect an rx buffer would get
|
||||
deallocated by mistake. After enough re-connects
|
||||
all reallocated rx buffers would run out,
|
||||
causing stop in commnunications.
|
||||
|
||||
o LIP Frame Relay Update
|
||||
Added Frame Relay API capability
|
||||
Added Frame Relay Q933 Signalling
|
||||
|
||||
|
||||
o Voice TDM for European Standars BRI
|
||||
|
||||
If you compile zaptel with the BRI
|
||||
patch, you must manually edit the
|
||||
|
||||
patches/kdrivers/src/net/sdla_tdmv.c file
|
||||
and uncomment the:
|
||||
CONFIG_ZAPATA_BRI_DCHANS option.
|
||||
|
||||
|
||||
o Lip Frame Relay API Support
|
||||
Update LIP API frame releay
|
||||
support
|
||||
|
||||
o General Driver Update
|
||||
Network interface behaviour on carrier
|
||||
disconnect.
|
||||
This update changes the network interface
|
||||
state in case of carrier state change.
|
||||
|
||||
TEQL will now work properly over AFT
|
||||
and LIP interfaces.
|
||||
|
||||
o TDM Voice
|
||||
Added on an extra option under the
|
||||
TDM network interface section:
|
||||
TDMV_ECHO_OFF=[YES/NO]
|
||||
|
||||
This option should be used to disable
|
||||
echo on particular span, since asterisk
|
||||
echo configuration is global to all spans.
|
||||
|
||||
This way echo cancellation can be performed
|
||||
only on a span that needs this service.
|
||||
|
||||
o Wanpipemon Update
|
||||
A more integrated wanpipemon that works with
|
||||
the different layers of LIP and AFT.
|
||||
|
||||
beta3-2.3.2
|
||||
Jan 04 2005
|
||||
|
||||
o A104 Quad Port TE1 Hardware Support
|
||||
|
||||
o X86_64 bit support for AMD Opteron and
|
||||
Intel Itanium.
|
||||
|
||||
o Lip layer TTY support for Multilink PPP
|
||||
Support up to 32 TTY links
|
||||
|
||||
o Major Bug Fix in LIP Layer
|
||||
The bug could result in unexpected behaviour
|
||||
on some distributions.
|
||||
|
||||
o Updated /proc/net/wanrouter/interface
|
||||
statistics.
|
||||
|
||||
o PPP Multilink Support for AFT and ADSL cards.
|
||||
Refer to wanpipe/doc/README.multilink
|
||||
|
||||
o Support for Fedora Core 3 distribution.
|
||||
|
||||
o Fixed support for REGPARM kernels.
|
||||
|
||||
o Updated Sangoma ASTERISK drivers.
|
||||
Voice TDM update for A104 drivers.
|
||||
|
||||
o wanpipemon update
|
||||
Works with LIP layer only.
|
||||
|
||||
o wanpipemon_legacy
|
||||
Works with legacy drivers.
|
||||
|
||||
o wancfg update
|
||||
Configures all drivers AFT,S514,ADSL
|
||||
using LIP layer only.
|
||||
|
||||
o wancfg_legacy created
|
||||
Used to configure legacy protocols
|
||||
and API's.
|
||||
|
||||
|
||||
beta2-2.3.2
|
||||
Nov 8 2004
|
||||
|
||||
o AFT Update
|
||||
Cleaned up messages in case of PCI errors
|
||||
|
||||
o TDM Voice Update
|
||||
Added echo cancelation to the Asterisk
|
||||
support.
|
||||
|
||||
|
||||
beta1-2.3.2
|
||||
Oct 18 2004
|
||||
|
||||
o Support for 2.6.X kernels
|
||||
Fixed broken support for 2.6.9 kernel
|
||||
|
||||
o New Hardware Abstracion Layer
|
||||
Cleanly separates the hardware
|
||||
layer from the data/protocol layers.
|
||||
|
||||
o New AFT Hardware Support
|
||||
Sangomas new high-speed T1/E1
|
||||
adapters.
|
||||
|
||||
o New AFT T3 Support
|
||||
Sangomas new high-speed T3/E3
|
||||
adapters
|
||||
|
||||
o New LIP Network Layer
|
||||
Separates Wanpipe hardware from
|
||||
the Network Protocols.
|
||||
Frame Relay Protocol
|
||||
CHDLC Protocol
|
||||
PPP Protocol
|
||||
LAPB API
|
||||
XDLC API
|
||||
|
||||
o New wancfg configuration utilty
|
||||
One can only configure:
|
||||
Frame Relay
|
||||
PPP,
|
||||
CHDLC,
|
||||
HDLC (RAW) (TDM VOICE)
|
||||
|
||||
Note:
|
||||
The old wancfg utility is called wancfg_adv.
|
||||
|
||||
|
||||
PRODUCT COMPONENTS AND RELATED FILES
|
||||
|
||||
/etc/wanpipe/: (or user defined)
|
||||
wanpipe1.conf default router configuration file
|
||||
|
||||
etc/wanpipe/samples:
|
||||
interface sample interface configuration file
|
||||
wanpipe1.cpri CHDLC primary port
|
||||
wanpipe2.csec CHDLC secondary port
|
||||
wanpipe1.fr Frame Relay protocol
|
||||
wanpipe1.ppp PPP protocol )
|
||||
wanpipe1.asy CHDLC ASYNC protocol
|
||||
wanpipe1.x25 X25 protocol
|
||||
wanpipe1.stty Sync TTY driver (Used by Kernel PPPD daemon)
|
||||
wanpipe1.atty Async TTY driver (Used by Kernel PPPD daemon)
|
||||
wanrouter.rc sample meta-configuration file
|
||||
|
||||
/etc/wanpipe/firmware:
|
||||
fr514.sfm Frame relay firmware for Sangoma S508/S514 card
|
||||
cdual514.sfm Dual Port Cisco HDLC firmware for Sangoma S508/S514 card
|
||||
ppp514.sfm PPP Firmware for Sangoma S508 and S514 cards
|
||||
x25_508.sfm X25 Firmware for Sangoma S508 card.
|
||||
bscmp514.sfm Multi point bisync
|
||||
edu_kit.sfm Education driver
|
||||
bitstrm.sfm Bit streaming firmware
|
||||
bscstrm514.sfm Bisync streaming firware
|
||||
|
||||
|
||||
/lib/modules/X.Y.Z/misc:
|
||||
wanrouter.o router kernel loadable module
|
||||
af_wanpipe.o wanpipe api socket module
|
||||
|
||||
/lib/modules/X.Y.Z/net:
|
||||
sdladrv.o Sangoma SDLA support module
|
||||
wanpipe.o Sangoma WANPIPE(tm) driver module
|
||||
syncppp.o Kernel Sync PPP module
|
||||
|
||||
/proc/net/wanrouter
|
||||
Config reads current router configuration
|
||||
Status reads current router status
|
||||
{name} reads WAN driver statistics
|
||||
|
||||
/usr/sbin:
|
||||
wanrouter wanrouter start-up script
|
||||
wanconfig wanrouter configuration utility
|
||||
sdladump WANPIPE adapter memory dump utility
|
||||
wanpipemon Debugging Monitor for all WANPIPE protocols
|
||||
wpkbdmon WANPIPE keyboard led monitor/debugger
|
||||
wancfg WANPIPE GUI configuration program.
|
||||
Creates wanpipe#.conf files.
|
||||
cfgft1 GUI CSU/DSU configuration program.
|
||||
|
||||
|
||||
wanpipe/ (temporary untar directory):
|
||||
README this file
|
||||
COPYING GNU General Public License
|
||||
Setup installation script
|
||||
Filelist distribution definition file
|
||||
wanrouter.rc meta-configuration file
|
||||
(used by the Setup and wanrouter script)
|
||||
|
||||
/usr/share/doc/wanpipe:
|
||||
WanpipeInstallation.pdf WAN Router User's Manual
|
||||
WanpipeInstallation.txt
|
||||
WanpipeConfiguration.pdf
|
||||
WanpipeConfiguration.txt
|
||||
WanpipeOperation.pdf
|
||||
WanpipeOperation.txt
|
||||
|
||||
wanpipe/patches:
|
||||
wanrouter-v2213.gz patch for Linux kernels 2.2.11 up to 2.2.13.
|
||||
wanrouter-v2214.gz patch for Linux kernel 2.2.14.
|
||||
wanrouter-v2215.gz patch for Linux kernels 2.2.15 to 2.2.17.
|
||||
wanrouter-v2218.gz patch for Linux kernels 2.2.18 and up.
|
||||
wanrouter-v240.gz patch for Linux kernel 2.4.0.
|
||||
wanrouter-v242.gz patch for Linux kernel 2.4.2.
|
||||
wanrouter-v243.gz patch for Linux kernel 2.4.3
|
||||
wanrouter-v244.gz patch for Linux kernel 2.4.4
|
||||
wanrouter-v245.gz patch for Linux kernel 2.4.5
|
||||
wanrouter-v246.gz patch for Linux kernel 2.4.6 and up
|
||||
wanrouter-v249.gz patch for Linux kernel 2.4.9 and up
|
||||
wanrouter-v2416.gz patch for Linux kenrel 2.4.16 and up
|
||||
wanrouter-v2034.gz patch for Linux kernel 2.0.34
|
||||
wanrouter-v2036.gz patch for Linux kernel 2.0.36 and up.
|
||||
|
||||
wanpipe/patches/kdrivers:
|
||||
Sources of the latest WANPIPE device drivers.
|
||||
These are used to UPGRADE the linux kernel to the newest
|
||||
version if the kernel source has already been pathced with
|
||||
WANPIPE drivers.
|
||||
|
||||
/etc/wanpipe/api/x25:
|
||||
* x25 api sample programs.
|
||||
/etc/wanpipe/api/chdlc:
|
||||
* chdlc api sample programs.
|
||||
/etc/wanpipe/api/fr:
|
||||
* fr api sample programs.
|
||||
|
||||
/usr/src/linux/include/linux:
|
||||
wanrouter.h router API definitions
|
||||
wanpipe.h WANPIPE API definitions
|
||||
sdladrv.h SDLA support module API definitions
|
||||
sdlasfm.h SDLA firmware module definitions
|
||||
if_wanpipe.h WANPIPE Socket definitions
|
||||
if_wanpipe_common.h WANPIPE Socket/Driver common definitions.
|
||||
sdlapci.h WANPIPE PCI definitions
|
||||
|
||||
|
||||
/usr/src/linux/net/wanrouter:
|
||||
* wanrouter source code
|
||||
/usr/src/linux/drivers/net/wan:
|
||||
sdla* and
|
||||
wanpipe* wanpipe source code
|
||||
|
||||
/var/log:
|
||||
wanrouter wanrouter start-up log (created by the Setup script)
|
||||
|
||||
/var/lock: (or /var/lock/subsys for RedHat)
|
||||
wanrouter wanrouter lock file (created by the Setup script)
|
||||
|
||||
|
|
@ -0,0 +1,396 @@
|
|||
WANPIPE PACKAGE INSTALLATION/UN-INSTALLATION
|
||||
============================================
|
||||
|
||||
Author: Nenad Corbic
|
||||
|
||||
|
||||
WANPIPE PACKAGES
|
||||
================
|
||||
|
||||
Wanpipe RPM packages are located in:
|
||||
ftp.sangoma.com/linux/RPMS
|
||||
|
||||
Please refer to RPM package installation
|
||||
below.
|
||||
|
||||
|
||||
Wanpipe SOURCE packages are located in:
|
||||
ftp.sangoma.com/linux/current_wanpipe
|
||||
|
||||
Download the latest SOURCE wanpipe release
|
||||
in ANY directory:
|
||||
ex: cd /tmp
|
||||
tar xvfz wanpipe-<version>.tgz
|
||||
|
||||
The tar will create the temporary
|
||||
wanpipe/ directory.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE SOURCE PACKAGE Installation
|
||||
====================================
|
||||
|
||||
The 'Setup' script located in temporary wanpipe/
|
||||
directory should be used to install/un-install
|
||||
and re-configure all WANPIPE driver and utilities.
|
||||
|
||||
The Setup installation script contains numerous
|
||||
options that can be used to customise wanpipe
|
||||
installation. Run ./Setup without any arguments
|
||||
for usage.
|
||||
|
||||
Run the Setup script from temporary wanpipe/ directory
|
||||
(wanpipe directory was created by untaring the source package)
|
||||
|
||||
cd wanpipe/
|
||||
|
||||
./Setup install
|
||||
|
||||
The install option will do the following:
|
||||
-------
|
||||
1. Check that all WANPIPE files are accounted for.
|
||||
|
||||
2. Check/modify permissions on all WANPIPE files.
|
||||
|
||||
3. Prompt the user to Install/Upgrade WANPIPE
|
||||
drivers into the Linux kernel source.
|
||||
|
||||
NOTE: The kernel source must be located
|
||||
in /usr/src/linux.
|
||||
|
||||
Or the linux source directory
|
||||
must be supplied with '--with-linux' argument.
|
||||
|
||||
It is always RECOMMENDED to upgrade/update
|
||||
the kernel source tree with the latest
|
||||
wanpipe source.
|
||||
|
||||
4. Prompt the user to re-compile all WANPIPE
|
||||
kernel drivers and install them as modules
|
||||
in the the current /lib/modules/<kernel-version>
|
||||
directory.
|
||||
|
||||
Compilaton Options: Default or Custom
|
||||
|
||||
Default compilation:
|
||||
option will compile the standard WANPIPE protocols
|
||||
into the kernel device driver: Frame Relay, PPP, CHDLC
|
||||
Multi-Port Frame Relay, Multi-Port PPP, and X25(API). "
|
||||
|
||||
Custom compilation:
|
||||
option will offer a menu of all available WAN and
|
||||
API protocols. The user will be able to enable
|
||||
protocols individually or all at once,
|
||||
as desired.
|
||||
|
||||
With this option, NO kernel recomilation is
|
||||
necessary :)
|
||||
|
||||
5. Prompt the user to install bootstrap
|
||||
scripts that will be used to start wanpipe
|
||||
during boot up.
|
||||
|
||||
6. Setup the ENVIRONMENT configuration file that will
|
||||
contain directory locations of WANPIPE configuration
|
||||
interface and lock files.
|
||||
|
||||
7. Compile all WANPIPE utilities
|
||||
|
||||
8. Setup the WANPIPE working environment.
|
||||
i.e. Install all binary files into
|
||||
linux file tree.
|
||||
|
||||
/etc/wanpipe : config, library, sample
|
||||
and firmware files.
|
||||
|
||||
/usr/sbin : user space, binary
|
||||
utilites
|
||||
|
||||
/lib/modules/<uname-r> : wanpipe kernel
|
||||
modules
|
||||
|
||||
/usr/share/doc/wanpipe : doc files
|
||||
|
||||
|
||||
The last message in the 'Setup install' sequence will
|
||||
inform you of the next step that you should take
|
||||
in getting WANPIPE working.
|
||||
|
||||
|
||||
o Read 'README-2.config' on how to configure wanpipe
|
||||
device
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CUSTOMIZING WANPIPE SOURCE INSTALLATION
|
||||
=========================================
|
||||
|
||||
Installation using the '--silent' option
|
||||
--------------------------------------
|
||||
|
||||
The '--silent' option is available to install wanpipe
|
||||
without any user interaction:
|
||||
|
||||
./Setup install --silent
|
||||
|
||||
All defaults will be used!
|
||||
--------------------------
|
||||
1. Configuration directory /etc/wanpipe
|
||||
2. Start wanpipe on boot up
|
||||
3. Recompile modules for the kenrel source
|
||||
in /usr/src/linux
|
||||
|
||||
|
||||
|
||||
Installation using the --builddir option
|
||||
--------------------------------------
|
||||
|
||||
When customising the wanpipe package, it is
|
||||
useful to install the package into a
|
||||
virtual directory so not to pollute the
|
||||
current environment.
|
||||
|
||||
This way a user can tar up the temporary
|
||||
directory and create a custom binary
|
||||
WANPIPE package.
|
||||
|
||||
eg ./Setup install --builddir=/tmp/wanpipe_build
|
||||
|
||||
Note: the /tmp/wanpipe_build directory must
|
||||
exist.
|
||||
|
||||
|
||||
|
||||
Installation using the --protocol option
|
||||
--------------------------------------
|
||||
|
||||
Standard Wanpipe installatin will only
|
||||
include MAINSTREAM WAN protocols when building
|
||||
the kernel modules to cut down on kernel
|
||||
module size.
|
||||
|
||||
Mainstream Protocols:
|
||||
Frame Relay, PPP, CHDLC, X25, API stack
|
||||
|
||||
|
||||
To enable NON Mainstream protocols specify
|
||||
extra protocols with the --protocol option.
|
||||
|
||||
Non Mainstream Protocols:
|
||||
BSC : API for Multipoint Bisync
|
||||
BSCSTRM : API for Bisync Streaming
|
||||
SS7 : API for Level2 SS7 protocol
|
||||
EDU : API for Educational software
|
||||
SDLC : API for SDLC protocol
|
||||
POS : API for POS (S515/S509) card.
|
||||
BITSTRM : API for Bitstreaming protocol
|
||||
|
||||
eg: ./Setup install --protocol=<List of Protocols>
|
||||
|
||||
<List of Protocols> = <PROT>-<PROT>-<PROT>
|
||||
|
||||
eg:
|
||||
Compile in Bitstreaming protocol
|
||||
./Setup install --protocol=BITSTRM
|
||||
|
||||
Compile in BitStreaming and POS and SDLC
|
||||
./Setup install --protocol=BITSTRM-POS-SDLC
|
||||
|
||||
|
||||
|
||||
Building a custom RPM
|
||||
---------------------
|
||||
|
||||
./Setup buildrpm <extra options>
|
||||
|
||||
All defaults will be used!
|
||||
--------------------------
|
||||
1. Configuration directory /etc/wanpipe
|
||||
2. Start wanpipe on boot up
|
||||
3. Recompile modules for the kernel source
|
||||
locatd in /usr/src/linux direcotory,
|
||||
or directory supplied with --with-linux=<abs path>
|
||||
argument.
|
||||
|
||||
|
||||
|
||||
Note: <extra options> start with -- and are defined above.
|
||||
|
||||
i.e.
|
||||
user the --protocol filed to add in extra protocols
|
||||
into the wanpipe kernel modules.
|
||||
|
||||
Refer to README.rpmbuild
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE Kernel Driver Compile/Update
|
||||
====================================
|
||||
|
||||
This option should be used to update the kernel
|
||||
source tree with the latest wanpipe drivers
|
||||
and to compile the wanpipe kernel modules
|
||||
against the updated kernel source tree.
|
||||
|
||||
Run the Setup script in temporary wanpipe/ directory:
|
||||
|
||||
ex: cd wanpipe/
|
||||
|
||||
./Setup drivers
|
||||
|
||||
The drivers option will do the following:
|
||||
-------
|
||||
1. Prompt the user to Install/Upgrade Wanpipe
|
||||
drivers into the Linux kernel source.
|
||||
|
||||
NOTE: The kernel source must be located
|
||||
in /usr/src/linux
|
||||
|
||||
It is always RECOMMENDED to upgrade/update
|
||||
the kernel source tree with the latest
|
||||
wanpipe source.
|
||||
|
||||
2. Prompt the user to re-compile all WANPIPE
|
||||
kernel drivers and install the as modules
|
||||
in the the current /lib/modules/<kernel-version>
|
||||
directory.
|
||||
|
||||
Compilaton Options: Default or Custom
|
||||
|
||||
Default compilation:
|
||||
option will compile the standard WANPIPE protocols
|
||||
into the kernel device driver: Frame Relay, PPP, CHDLC
|
||||
Multi-Port Frame Relay, Multi-Port PPP, and X25(API). "
|
||||
|
||||
Custom compilation:
|
||||
option will offer a menu of all available WAN and
|
||||
API protocols. The user will be able to enable
|
||||
protocols individually or all at once,
|
||||
as desired.
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE Utilities Re-Compilation
|
||||
=================================
|
||||
|
||||
This option will re-compile all WANPIPE utilities
|
||||
in temporary wanpipe/ directory.
|
||||
|
||||
NOTE: If this is a first time install you MUST run
|
||||
the install option: Setup install.
|
||||
|
||||
Run the Setup script in temporary wanpipe/ directory:
|
||||
|
||||
ex: cd wanpipe/
|
||||
./Setup utility
|
||||
|
||||
The utility option will do the following:
|
||||
-------
|
||||
1. Compile all WANPIPE utilities
|
||||
in temporary wanpipe/ directory
|
||||
|
||||
To install utilities into /usr/sbin
|
||||
directory one must run:
|
||||
|
||||
./Setup inst
|
||||
|
||||
|
||||
For more info about Setup command run
|
||||
./Setup without any arguments for full usage
|
||||
info.
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE Un-Install
|
||||
==================
|
||||
|
||||
Run the Setup script in temporary wanpipe/ directory:
|
||||
|
||||
ex: cd wanpipe/
|
||||
./Setup remove
|
||||
|
||||
|
||||
The remove option will do the following:
|
||||
------
|
||||
1. Remove all boot strap WANPIPE scripts.
|
||||
2. Remove all utilities from /usr/sbin,
|
||||
/etc/wanpipe, /usr/share/doc/wanpipe
|
||||
directories.
|
||||
|
||||
After the 'Setup remove' command, it is safe
|
||||
to remove the whole temporary wanpipe/ directory.
|
||||
|
||||
ex:
|
||||
rm -rf wanpipe/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE RPM PACKAGE Installation
|
||||
================================
|
||||
|
||||
Choosing an RPM:
|
||||
--------------
|
||||
|
||||
o Determine the Linux Distribution:
|
||||
cat /etc/issue
|
||||
(eg: RedHat 7.1)
|
||||
|
||||
o Determine the Kernel image you are running:
|
||||
uname -r
|
||||
(eg: 2.4.2-2 : it is not an smp kernel)
|
||||
(eg: 2.4.2-2smp : smp kernel)
|
||||
|
||||
o Determine the processor type
|
||||
uname -m
|
||||
(eg: i686)
|
||||
|
||||
o Based on the above information choose an RPM package.
|
||||
|
||||
wanpipe-<version>.<linux distrib>.<kernel ver>.<processor>.rpm
|
||||
|
||||
eg: ftp.sangoma.com/linux/RPM/redhat/7.1/i686/
|
||||
wanpipe-2.2.4-3.rh71up.k242-2.i686.rpm
|
||||
|
||||
|
||||
|
||||
Installing RPM
|
||||
----------
|
||||
|
||||
o List the contents of the rpm
|
||||
|
||||
rpm -qipl <wanpipe rpm name>
|
||||
|
||||
Make sure that the /lib/modules/<kernel name> directory
|
||||
matches your current kernel modules directory.
|
||||
|
||||
i.e. the output of command 'uname -r' must match the above
|
||||
<kernel name> directory.
|
||||
|
||||
|
||||
o The rpm must be installed using the --force option, to
|
||||
override the old modules.
|
||||
|
||||
rpm -i --force <wanpipe rpm name>
|
||||
|
||||
|
||||
o Read 'README-2.config' on how to configure wanpipe
|
||||
device
|
||||
|
||||
|
||||
|
||||
For further info, refer to WanpipeInstallation.pdf
|
|
@ -0,0 +1,376 @@
|
|||
Wanpipe Configuration
|
||||
======================
|
||||
|
||||
Before starting WANPIPE, a configuration file (wanpipeN.conf, where
|
||||
N=1,2,3..etc.)must be created in /etc/wanpipe directory.
|
||||
This file contains the line, hardware and interface definitions
|
||||
for the WAN connection.
|
||||
|
||||
RELEASE 2.3.2 and on:
|
||||
The new WANCFG utility has been release. It should
|
||||
be used to configure standard WAN protocols like:
|
||||
FR, PPP, CHDLC,
|
||||
MULTILINK PPP (TTY), TDM_VOICE
|
||||
HDLC API
|
||||
ADSL
|
||||
|
||||
|
||||
For both AFT and S514 series cards.
|
||||
|
||||
The old WANCFG utility has been renamed to wancfg_legacy.
|
||||
This utility should be used for all API protocols like:
|
||||
X25, SDLC, BITSTREAMING ...
|
||||
|
||||
|
||||
The program /usr/sbin/wancfg should be used to create the
|
||||
configuration file(s). It is a GUI, ncurses based,
|
||||
configurator that contains all wanpipe options
|
||||
as well as extended help information on each
|
||||
option.
|
||||
|
||||
In case wancfg is not used, i.e. embedded systems, use
|
||||
the sample configuration files located in
|
||||
/etc/wanpipe/samples directory.
|
||||
|
||||
|
||||
Things you should know before starting /usr/sbin/wancfg:
|
||||
|
||||
1. Protocol:
|
||||
Frame Relay, MulitPort Frame Relay,
|
||||
CHDLC, PPP, MultiPort PPP, ADSL, X25 ...
|
||||
|
||||
2. Protocol/IP Info:
|
||||
Frame Relay: Type of Status Signaling (LMI,
|
||||
ANSI, or Q.933
|
||||
Number of DLCI to configure
|
||||
DLCI numbers
|
||||
IP info for each DLCI
|
||||
|
||||
CHDLC: IP info
|
||||
|
||||
PPP: IP info
|
||||
|
||||
X25: Maximum packet size
|
||||
Number of SVCs/PVCs
|
||||
IP info
|
||||
|
||||
ADSL: ATM encapsulation:
|
||||
Bridged Ethernet LLC over ATM: (PPPoE)
|
||||
Bridged Ethernet VC over ATM
|
||||
Classical IP LLC over ATM
|
||||
Router IP VC over ATM
|
||||
PPP LLC over ATM
|
||||
PPP VC over ATM: (PPPoA)
|
||||
|
||||
ATM configuration:
|
||||
VPI and VCI
|
||||
|
||||
If not available use the auto
|
||||
config option to autodetect
|
||||
these values.
|
||||
|
||||
IP Info: (Not needed for PPPoE)
|
||||
|
||||
NOTE:
|
||||
For PPPoE and PPPoA setup please refer to
|
||||
APPENDIX A below.
|
||||
|
||||
ATM: ATM encapsulation:
|
||||
Bridged Ethernet LLC over ATM: (PPPoE)
|
||||
Bridged Ethernet VC over ATM
|
||||
Classical IP LLC over ATM
|
||||
Router IP VC over ATM
|
||||
|
||||
ATM configuration:
|
||||
VPI and VCI
|
||||
|
||||
IP Info: (Not needed for PPPoE)
|
||||
|
||||
3. CSU/DSU Info:
|
||||
|
||||
T1/E1: Encoding
|
||||
Framing
|
||||
Active Channels/Baud Rate
|
||||
|
||||
56K: Internal or External Clocking
|
||||
Internal clocking should only be used
|
||||
in back to back situations.
|
||||
Default: External
|
||||
|
||||
|
||||
For the rest of this document, we will assume we are working with the
|
||||
following ISP/Telco supplied data:
|
||||
|
||||
|
||||
Protocol: Frame Relay
|
||||
Prot Info:
|
||||
Num of DLCI's = 2
|
||||
DLCI=16 and 17
|
||||
|
||||
IP Info: DLCI 16
|
||||
Local =201.1.1.1
|
||||
PtoP =201.1.1.2
|
||||
Netmask =255.255.255.0
|
||||
Gateway =201.1.1.2 (i.e. this is the system
|
||||
default gateway)
|
||||
|
||||
DLCI 17
|
||||
Local =202.1.1.1
|
||||
PtoP =202.1.1.2
|
||||
Netmask =255.255.255.0
|
||||
Gateway =N/A
|
||||
|
||||
|
||||
|
||||
WANCFG
|
||||
======
|
||||
|
||||
IMPORTANT:
|
||||
Use the "ADVANCED" sections only for non
|
||||
standard configurations, otherwise leave
|
||||
them default.
|
||||
|
||||
|
||||
1. Start /usr/sbin/wancfg
|
||||
|
||||
2. Select Create opton
|
||||
|
||||
3. Select Card from Hardware Probe
|
||||
|
||||
4. Specify Hardware information:
|
||||
T1/E1/V35
|
||||
|
||||
5. Specify Protocol
|
||||
FR,PPP,CHDLC,TTY(Multilink PPP) ...
|
||||
|
||||
Frame Relay is by default configured
|
||||
for Auto DLCI. Use the advanced sections
|
||||
to change this.
|
||||
|
||||
6. Network Interface Setup
|
||||
|
||||
Specify Operation mode:
|
||||
|
||||
WANPIPE: IP mode proceed to specify IP addresss
|
||||
API: Custom API mode, no IP addresses
|
||||
|
||||
Specify IP addresses:
|
||||
|
||||
7. Save and exit
|
||||
|
||||
|
||||
For old WANCFG_LEGACY example refer to APPENDIX B below!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Troubleshooting the driver load process
|
||||
=======================================
|
||||
|
||||
After a startup failure run wanrouter debug
|
||||
option for more information and possible solutions:
|
||||
|
||||
wanrouter debug
|
||||
|
||||
|
||||
Syntax Errors:
|
||||
--------------
|
||||
|
||||
All wanpipe configuration file syntax errors are
|
||||
reported in /var/log/wanrouter
|
||||
|
||||
wanrouter conflogs
|
||||
|
||||
|
||||
Driver Messages:
|
||||
----------------
|
||||
|
||||
All wanpipe driver events will be recorded in
|
||||
/var/log/messages.
|
||||
|
||||
Thus if errors occur, first check /var/log/messages
|
||||
to find out what exactly went wrong
|
||||
with the drivers startup.
|
||||
|
||||
wanrouter messages
|
||||
|
||||
or
|
||||
|
||||
tail -f /var/log/messages
|
||||
|
||||
Once the device is started you should see a
|
||||
"link connecting" message. This message
|
||||
indicates that the card was been configured
|
||||
successfully and that the link is trying to
|
||||
connect.
|
||||
|
||||
|
||||
Wanpipe Debugger:
|
||||
-----------------
|
||||
|
||||
/usr/sbin/wanpipemon should be used to further debug
|
||||
hardware, line and protocol problems.
|
||||
|
||||
/usr/sbin/wanpipemon -g
|
||||
|
||||
|
||||
|
||||
Sangoma Tech Support:
|
||||
---------------------
|
||||
|
||||
When reporting problems to Sangoma Tech Support please
|
||||
dump the current system debug information into
|
||||
a temporary file and send it via email.
|
||||
|
||||
1. wanrouter debug if_name > sangoma_debug_file.txt
|
||||
(where if_name is wanpipe interface name: eg wp1fr16)
|
||||
|
||||
2. Wait for 2-5 minutes
|
||||
|
||||
3. Stop the debug by pressing ENTER
|
||||
|
||||
4. Email sangoma_debug_file.txt to Sangoma Tech Support
|
||||
|
||||
|
||||
Refer to README-4.debugging
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
APPENDIX A: ADSL PPPoE and PPPoA Configuration
|
||||
==========
|
||||
|
||||
Refer to README.adsl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
APPENDIX B: WANCFG_LEGACY (Old Configurator)
|
||||
==========
|
||||
|
||||
1. Start /usr/sbin/wancfg
|
||||
|
||||
2. Select 'Create' option
|
||||
|
||||
3. Select a wanpipe device.
|
||||
If this is a first device select wanpipe1
|
||||
and hit <SELECT> button.
|
||||
|
||||
4. Choose a protocol
|
||||
In this case choose Frame Relay and hit <BACK>
|
||||
button.
|
||||
|
||||
5. Select Hardware Setup
|
||||
|
||||
Probing Hardware:
|
||||
The top option is "Probe Hardware"
|
||||
Select this option and press <ENTER>
|
||||
|
||||
Select a device. When selecting devices
|
||||
note the PORT option. Usually PORT=PRI
|
||||
would be used.
|
||||
|
||||
IMPORTANT:
|
||||
~~~~~~~~~~
|
||||
After the hardware probe section you will
|
||||
notice that the next four fields have
|
||||
been filled out. Thus, adapter type and
|
||||
PCI info should be skipped.
|
||||
|
||||
|
||||
All other options should normally be left as
|
||||
DEFAULT unless you have special information.
|
||||
|
||||
Exit Hardware Setup
|
||||
|
||||
|
||||
6. Network Interface Setup
|
||||
|
||||
|
||||
The network interface set-up depends on the type of connection.
|
||||
|
||||
Instance Frame Relay supports many interfaces, each boud to
|
||||
a DLCI. Thus, there are questions related to the number of
|
||||
DLCIs and configuration information for each DLCI.
|
||||
|
||||
In the case of Point-to-Point protocols like PPP and CHDLC, there
|
||||
is only one interface per physical port.
|
||||
|
||||
This example is Frame Relay with two DLCIs. The first input is:
|
||||
"Please specify the number of DLCIs supported on this Frame Relay
|
||||
connection"
|
||||
|
||||
Enter in number 2
|
||||
|
||||
|
||||
For each network interface do the following:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
DLCI Number:
|
||||
Enter in the DLCI number. Note the default number
|
||||
is always 16.
|
||||
|
||||
Interface Name:
|
||||
The Interface name will also have default value.
|
||||
You can leave it as is or change it. For instance,
|
||||
you could change it to ?chicago? or ?toronto?.
|
||||
|
||||
IMPORTANT:
|
||||
~~~~~~~~~
|
||||
If you are using iptables you might want to change
|
||||
the default interface name to something like "wan0".
|
||||
Iptables and Ipchains don't like "_" in interface
|
||||
name.
|
||||
|
||||
e.g.: 'iptables -o wp1_fr16 ...' will give you an error
|
||||
|
||||
Operation Mode:
|
||||
WANPIPE is for IP Routing
|
||||
BRIDGE is used to attach the network interface to
|
||||
the kernel bridge
|
||||
BRIDGE_NODE is used as a remote end of the line that is
|
||||
connected to a bridge.
|
||||
API is used for custom API applications.
|
||||
Custom socket access to driver.
|
||||
|
||||
DLCI Protocol Setup:
|
||||
In this section leave everything as default.
|
||||
Unless the ISP has specified specific protocol
|
||||
options such as CIR.
|
||||
|
||||
IP Setup:
|
||||
Put in your IP info as supplied by ISP
|
||||
Enable Default gateway for the first
|
||||
interface.
|
||||
|
||||
Note: PointoPoint IP refers to the IP address of
|
||||
the remote router that is connected at
|
||||
the other end of the sync line.
|
||||
|
||||
|
||||
7. Once all network interfaces are setup
|
||||
keep hitting the <BACK> button until
|
||||
Main Menu is reached.
|
||||
|
||||
Then select <EXIT> and save the config
|
||||
file.
|
||||
|
||||
The new config file will be located in
|
||||
/etc/wanpipe directory.
|
||||
|
||||
|
||||
8. Start the device:
|
||||
wanrouter start wanpipe1
|
||||
|
||||
Note: The card doesn't have to be connected to start the wanrouter.
|
||||
|
||||
|
|
@ -0,0 +1,328 @@
|
|||
Wanpipe Operation Manual
|
||||
========================
|
||||
|
||||
|
||||
At the heart of WANPIPE operation is the 'wanrouter' operation
|
||||
script. It is used to start/stop/restart and display
|
||||
WANPIPE current status and environment.
|
||||
|
||||
|
||||
'wanrouter' usage
|
||||
=================
|
||||
|
||||
/usr/sbin/wanrouter <cr>
|
||||
|
||||
|
||||
WANPIPE: WAN Router startup script
|
||||
|
||||
Usage: wanrouter: {options} <wanpipe#> <interface>
|
||||
|
||||
wanrouter start : Starts all devices specified in
|
||||
/etc/wanpipe/wanrouter.rc WAN_DEVICES
|
||||
|
||||
wanrouter stop : Stops all devices specified in
|
||||
/etc/wanpipe/wanrouter.rc WAN_DEVICES
|
||||
|
||||
wanrouter start wanpipe# : Start a single device
|
||||
|
||||
wanrouter stop wanpipe# : Stops a single device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
wanrouter restart : Restart all devices specified in
|
||||
/etc/wanpipe/wanrouter.rc WAN_DEVICES
|
||||
|
||||
wanrouter restart wanpipe# : Restart a single device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
|
||||
wanrouter start wanpipe# if_name : Start a single interface on device
|
||||
|
||||
wanrouter stop wanpipe# if_name : Stops a single interface on device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
wanrouter restart wanpipe# if_name : Restart a single interface on device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
|
||||
wanrouter list : List all active devices
|
||||
|
||||
wanrouter modules : Show wanpipe kernel modules
|
||||
|
||||
wanrouter status : Display status for all active devices
|
||||
|
||||
wanrouter summary : Summary of config files in /etc/wanpipe
|
||||
|
||||
wanrouter hwprobe : Display wanpipe hardware probe info.
|
||||
|
||||
wanrouter debug : Check current wanpipe environment.
|
||||
Wanpipe startup debugging. After a startup error
|
||||
run this command to get a possible solution
|
||||
i.e. wanrouter start; wanrouter debug;
|
||||
|
||||
wanrouter debug if_name : Display common debugging statistics
|
||||
In case of line problems save to file, wait 2-5min
|
||||
and send to Sangoma Tech Support
|
||||
i.e. wanrouter debug wp1fr16 > debug_file;
|
||||
|
||||
wanrouter conflogs : Display wanpipe configuration syntax errors
|
||||
i.e. /var/log/wanrouter
|
||||
|
||||
|
||||
wanrouter messages : Display wanpipe kernel event messages
|
||||
i.e. /var/log/messages
|
||||
|
||||
|
||||
wanrouter version : wanpipe version information.
|
||||
|
||||
|
||||
|
||||
WANPIPE Environment Check
|
||||
=========================
|
||||
|
||||
The wanrouter debug option will check current
|
||||
wanpipe environment, make sure that kernel modules
|
||||
do load, and that /var/log/messages and /var/log/wanrouter
|
||||
logs do not show any errors. It will also try
|
||||
to give possible solutions.
|
||||
|
||||
/usr/sbin/wanrouter debug
|
||||
|
||||
|
||||
Make sure that the new WANPIPE kernel modules have
|
||||
been installed correcty and that they can be loaded
|
||||
into the kernel, and the hardware is detected.
|
||||
|
||||
/usr/sbin/wanrouter hwprobe
|
||||
|
||||
|
||||
Check that a configuration file exists in /etc/wanpipe
|
||||
directory.
|
||||
|
||||
/usr/sbin/wanrouter summary
|
||||
|
||||
|
||||
Make sure that no WANPIPE devices are currently running
|
||||
on the system
|
||||
|
||||
/usr/sbin/wanrouter list
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE Startup
|
||||
===============
|
||||
|
||||
Please note that all kernel driver output messages are
|
||||
located in /var/log/messages file.
|
||||
|
||||
Run 'tail -f /var/log/messages' in a separate console
|
||||
window, to monitor WANPIPE start/stop and operation
|
||||
messages.
|
||||
|
||||
|
||||
To start/stop/restart WANPIPE devices listed in
|
||||
/etc/wanpipe/wanrouter.rc file: (default is wanpipe1)
|
||||
|
||||
/usr/sbin/wanrouter start
|
||||
/usr/sbin/wanrouter stop
|
||||
/usr/sbin/wanrouter restart
|
||||
|
||||
|
||||
To start/stop/restart single wanpipe device: (eg: wanpipe2)
|
||||
|
||||
This command is useful when running multiple devices
|
||||
and would like to operate on a singe device.
|
||||
|
||||
/usr/sbin/wanrouter start wanpipe2
|
||||
/usr/sbin/wanrouter stop wanpipe2
|
||||
/usr/sbin/wanrouter restart wanpipe2
|
||||
|
||||
|
||||
To start/stop/restart a single network interface from a
|
||||
/etc/wanpipe/wanpipe1.conf configuration file:
|
||||
|
||||
This command is useful when adding an extra frame
|
||||
relay DLCI. Also to reconfigure a single DLCI.
|
||||
|
||||
/usr/sbin/wanrouter start wanpipe2 wp2_fr18
|
||||
/usr/sbin/wanrouter stop wanpipe2 wp2_fr18
|
||||
/usr/sbin/wanrouter restart wanpipe2 wp2_fr18
|
||||
|
||||
|
||||
To view current status and configuration of active
|
||||
devices:
|
||||
|
||||
/usr/sbin/wanrouter status
|
||||
|
||||
|
||||
|
||||
Error Debugging
|
||||
===============
|
||||
|
||||
After a failed wanrouter start command
|
||||
run:
|
||||
wanrouter debug
|
||||
|
||||
The debug option will identify an error and
|
||||
offer solutions.
|
||||
|
||||
|
||||
Configuration Syntax Errors:
|
||||
|
||||
All configuration file syntax errors, generated
|
||||
during WANPIPE starup, will be displayed in:
|
||||
|
||||
/var/log/wanrouter
|
||||
|
||||
(eg: cat /var/log/wanrouter)
|
||||
|
||||
|
||||
|
||||
Kernel Driver Errors:
|
||||
|
||||
All device driver errors and events will be
|
||||
displayed in:
|
||||
|
||||
/var/log/messages
|
||||
|
||||
(eg: tail -f /var/log/messages)
|
||||
|
||||
|
||||
Line Errors and Driver Statistics
|
||||
|
||||
After a successful WANPIPE startup any extra
|
||||
debugging, such as line tracing or CSU/DSU
|
||||
debugging will be done using:
|
||||
|
||||
/usr/sbin/wanpipemon -g
|
||||
|
||||
|
||||
For automated Line Error debugging run
|
||||
|
||||
/usr/sbin/wanrouter debug <if_name>
|
||||
|
||||
where <if_name> is wanpipe interface name.
|
||||
|
||||
|
||||
Sangoma Tech Support:
|
||||
---------------------
|
||||
|
||||
When reporting problems to Sangoma Tech Support please
|
||||
dump the current system debug information into
|
||||
a temporary file and send it via email.
|
||||
|
||||
1. wanrouter debug if_name > sangoma_debug_file.txt
|
||||
(where if_name is wanpipe interface name: eg wp1fr16)
|
||||
|
||||
2. Wait for 2-5 minutes
|
||||
|
||||
3. Stop the debug by pressing ENTER
|
||||
|
||||
4. Email sangoma_debug_file.txt to Sangoma Tech Support
|
||||
|
||||
|
||||
Pleae refer to README-4.debugging
|
||||
|
||||
|
||||
|
||||
Wanpipe Power User Operation
|
||||
-----------------------------
|
||||
|
||||
Wanpipe package contents
|
||||
========================
|
||||
|
||||
|
||||
1. Wanpipe Kernel Drivers
|
||||
|
||||
The drivers are listed in order of
|
||||
dependency.
|
||||
|
||||
sdladrv.o : Hardware Layer
|
||||
wanrouter.o : Wanpipe Protocol Interface Layer
|
||||
wanpipe_syncpp.o: Wanpipe PPP/CHDLC Protocol
|
||||
wanpipe.o : Wanpipe multi-protocol layer
|
||||
(Frame-Relay,PPP,CHDLC,...)
|
||||
af_wanpipe.o : Wanpipe API socket layer
|
||||
|
||||
|
||||
|
||||
2. User space programs
|
||||
|
||||
Configuration (/usr/sbin)
|
||||
|
||||
wancfg : Wanpipe configuration tool
|
||||
|
||||
cfgft1 : Wanpipe FT1 config tool for
|
||||
S508FT1 and S5143 cards
|
||||
(For all other cards use wancfg)
|
||||
|
||||
Operation (/usr/sbin)
|
||||
|
||||
wanconfig : Wanpipe operation tool that
|
||||
parses the config file and
|
||||
executed config ioctl() calls to
|
||||
the kernel driver.
|
||||
(C program)
|
||||
|
||||
wanconfig -a /etc/wanpipe/wan_adsl.list card wanpipe1 up
|
||||
|
||||
|
||||
wanrouter : Wanpipe operation script
|
||||
used to start/stop/restart
|
||||
Wanpipe drivers. The wanrouter
|
||||
script uses the above wanconfig
|
||||
to start wanpipe as well as
|
||||
standard "ifconfig" to bring
|
||||
all necessary interfaces up.
|
||||
|
||||
Debugging
|
||||
|
||||
wanpipemon : Wanpipe debugging application
|
||||
used to debug the hardware, drivers
|
||||
and sync line.
|
||||
|
||||
wanpipemon -g
|
||||
|
||||
|
||||
Wanpipe Operation
|
||||
=================
|
||||
|
||||
If a power user desn't want to use
|
||||
the wanrouter master script. Here is the
|
||||
break down of the wanpipe startup
|
||||
sequence:
|
||||
|
||||
wanrouter start
|
||||
|
||||
|
||||
1. Load Kernel Modules
|
||||
|
||||
insmod sdladrv.o
|
||||
insmod wanrouter.o
|
||||
insmod wanpipe_syncppp.o
|
||||
insmod wanpipe.o
|
||||
insmod af_wanpipe.o
|
||||
or
|
||||
|
||||
modprobe af_wanpipe
|
||||
|
||||
2. Configure and Start Drivers
|
||||
|
||||
/usr/sbin/wanconfig -a /etc/wanpipe/wan_adsl.list card wanpipe1 up
|
||||
|
||||
3. Start up all network interfaces
|
||||
|
||||
ifconfig wan0 <local ip> pointopoint <remote ip> netmask 255.255.255.255
|
||||
|
||||
4. Confirmation
|
||||
|
||||
tail -f /var/log/messages
|
||||
|
||||
Check the events and driver statistics.
|
||||
|
||||
cat /proc/net/wanrouter/status
|
||||
|
||||
Check driver state
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
Wanpipe Debugging Manual
|
||||
========================
|
||||
|
||||
Automated Debugging:
|
||||
--------------------
|
||||
|
||||
The wanrouter operation script can retrieve the
|
||||
most common line error statistics that can
|
||||
give the user a good idea of what is going on
|
||||
with the line.
|
||||
|
||||
/usr/sbin/wanrouter debug if_name
|
||||
or
|
||||
/usr/sbin/wanrouter debug if_name > debug_file.txt
|
||||
|
||||
(where if_name is the name of wanpipe interface: eg: wp1fr16)
|
||||
|
||||
|
||||
Sangoma Tech Support:
|
||||
---------------------
|
||||
|
||||
When reporting problems to Sangoma Tech Support please
|
||||
dump the current system debug information into
|
||||
a temporary file and send it via email.
|
||||
|
||||
1. wanrouter debug wp1fr16 > sangoma_debug_file.txt
|
||||
|
||||
2. Wait for 2-5 minutes
|
||||
|
||||
3. Stop the debug by pressing ENTER
|
||||
|
||||
4. Email sangoma_debug_file.txt to Sangoma Tech Support
|
||||
|
||||
|
||||
|
||||
Wanpipe Debugger
|
||||
----------------
|
||||
|
||||
At the heart of WANPIPE debugging is the 'wanpipemon'
|
||||
debugging program. It is used to display line
|
||||
traces, protocol statistics, hardware statistics
|
||||
and configuration parameters.
|
||||
|
||||
|
||||
/usr/sbin/wanpipemon -g
|
||||
|
||||
|
||||
'wanpipemon' usage
|
||||
==================
|
||||
|
||||
/usr/sbin/wanpipemon
|
||||
|
||||
Wanpipemon Verison 1.0
|
||||
Copyright (C) 2002 - Sangoma Technologies
|
||||
www.sangoma.com
|
||||
This may be freely redistributed under the terms of the GNU GPL
|
||||
|
||||
Usage: (Options in {} brackets are optional)
|
||||
|
||||
#Command prompt Local debugging
|
||||
wanpipemon -i <interface> -c <command> { -p <protocol> }
|
||||
|
||||
#Command prompt Remote debugging
|
||||
wanpipemon -i <remote IP> -u <port> -c <command> { -p <protocol> }
|
||||
|
||||
#GUI interface
|
||||
wanpipemon -g { -i <interface|IP> -u <port> -p <protocol> }
|
||||
|
||||
#Display usage for each protocol
|
||||
wanpipemon -p [fr|ppp|chdlc|x25|adsl]
|
||||
|
||||
#Detailed usage for each option
|
||||
wanpipemon -h
|
||||
|
||||
|
||||
The 'wanpipemon' utility operates in two modes.
|
||||
|
||||
Local debugging:
|
||||
The 'wanpipemon' utility is located on the same
|
||||
machine as the WANPIPE card.
|
||||
|
||||
Thus, the wanpipemon utility needs only the
|
||||
interface name (eg: wp1_fr16) to reach the driver.
|
||||
|
||||
/usr/sbin/wanpipemon -i wp1_fr16 -c xm
|
||||
|
||||
|
||||
Remote debugging:
|
||||
The 'wanpipemon' utility is located on a network
|
||||
(LAN or WAN) and must use the UDP protocol to
|
||||
reach the WANPIPE card.
|
||||
|
||||
In this case an IP and UDP addresses must be
|
||||
specified, such that the packet will pass through
|
||||
the WANPIPE driver!
|
||||
|
||||
Meaning a POINTOPOINT address must be used instead
|
||||
of the LOCAL IP address.
|
||||
|
||||
The UDP port was specified in WANPIPE configuration
|
||||
file. (Default=9000)
|
||||
|
||||
/usr/sbin/wanpipemon -i 201.1.1.2 -u 9000 -c xm
|
||||
|
||||
|
||||
GUI Mode Operation
|
||||
==================
|
||||
|
||||
The GUI mode is based on ncurses libraries, thus it
|
||||
will work both in Terminal or Xwindows mode.
|
||||
|
||||
/usr/sbin/wanpipemon -g
|
||||
|
||||
Without any other arguments the GUI will offer a list
|
||||
of network interfaces, for local debugging, or will
|
||||
ask for an IP/UDP address, for remote debugging.
|
||||
|
||||
Use menu's to navigate through available commands.
|
||||
|
||||
|
||||
|
||||
Common Statistics
|
||||
=================
|
||||
|
||||
|
||||
Modem Status (-c xm):
|
||||
|
||||
(wanpipemon -i if_name -c xm)
|
||||
|
||||
Must be DCD=HIGH and CTS=HIGH if not there is
|
||||
ether a cable problem or the sync line is
|
||||
not turned ON.
|
||||
|
||||
Comm Error Stats (-c sc):
|
||||
|
||||
(wanpipemon -i if_name -c sc)
|
||||
|
||||
Check for CRC and Abort errors. If errors
|
||||
are incrementing, there is a line issue.
|
||||
|
||||
Possible reasons: CSU/DSU misconfiguration
|
||||
on local or remote side.
|
||||
|
||||
Noisy/Bad line.
|
||||
|
||||
|
||||
Line trace (-c tr):
|
||||
|
||||
(wanpipemon -i if_name -c tr)
|
||||
|
||||
Make sure thare are incoming and outgoing frames.
|
||||
|
||||
If frames are outgoing and none incoming:
|
||||
|
||||
Frame relay: Check signalling (ANSI, LMI)
|
||||
|
||||
Make sure ISP uses IETF or CISCO
|
||||
data encapsulation.
|
||||
|
||||
Other prot: Possible CRC errors in TX
|
||||
direction. Contact your ISP.
|
||||
|
||||
|
||||
If frames are both incoming and outgoing but
|
||||
protocol is still down:
|
||||
|
||||
Run trace in Interpreted mode (-c ti) and
|
||||
make sure that the incoming protocol is
|
||||
indeed the one you are configured for.
|
||||
|
||||
|
||||
Wanpipe Kernel Messages
|
||||
|
||||
/usr/sbin/wanrouter messages
|
||||
or
|
||||
tail -f /var/log/messages
|
||||
|
||||
All line/protocol events will be displayed in
|
||||
the kernel logs.
|
|
@ -0,0 +1,26 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-2000 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
SYSINC=/usr/src/linux/include
|
||||
APIINC=/etc/wanpipe/api/include
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all:
|
||||
make -C x25 all SYSINC=$(SYSINC) APIINC=$(APIINC)
|
||||
make -C chdlc all SYSINC=$(SYSINC) APIINC=$(APIINC)
|
||||
make -C fr all SYSINC=$(SYSINC) APIINC=$(APIINC)
|
||||
make -C bitstrm all SYSINC=$(SYSINC) APIINC=$(APIINC)
|
||||
make -C bisync all SYSINC=$(SYSINC) APIINC=$(APIINC)
|
||||
# make -C ss7 all SYSINC=$(SYSINC) APIINC=$(APIINC)
|
||||
|
||||
clean:
|
||||
make -C x25 clean
|
||||
make -C chdlc clean
|
||||
make -C fr clean
|
||||
make -C bitstrm clean
|
||||
make -C bisync clean
|
||||
# make -C ss7 clean
|
|
@ -0,0 +1,67 @@
|
|||
WANPIPE API SAMPLE PROGRAMS
|
||||
===========================
|
||||
|
||||
Author: Nenad Corbic
|
||||
|
||||
|
||||
Note: These applications are NOT supported for
|
||||
kernels lower than 2.2.X.
|
||||
API drivers and applicatons are ONLY
|
||||
suppoted in 2.2.X kernels and greater.
|
||||
|
||||
This directory contains:
|
||||
|
||||
X25: WANPIPE X25 API sample programs. These programs
|
||||
should be used for rapid x25 api development,
|
||||
and initial testing.
|
||||
|
||||
FR: WANPIPE Frame Relay API sample programs. These programs
|
||||
should be used for rapid frame relay api development,
|
||||
and initial testing.
|
||||
|
||||
CHDLC: WANPIPE CHDLC API sample programs. These programs
|
||||
should be used for rapid chlc api development,
|
||||
and initial testing.
|
||||
|
||||
BITSTRM: WANPIPE BitStreaming API sample programs. These programs
|
||||
should be used for rapid bitstreaming api development,
|
||||
and initial testing.
|
||||
|
||||
BiSync: WANPIPE BiSync API sample programs. These programs
|
||||
should be used for rapid BiSync api development,
|
||||
and initial testing.
|
||||
|
||||
|
||||
Special Products
|
||||
----------------
|
||||
|
||||
Note, driver for these products are not installed
|
||||
by default. They must be specfined during the
|
||||
installation process to the ./Setup script.
|
||||
|
||||
|
||||
BiSync_strm:
|
||||
WANPIPE BiSync Streaming API sample programs. These programs
|
||||
should be used for rapid BiSync Streamin api development,
|
||||
and initial testing. Used specificly for NASDAQ feeds.
|
||||
|
||||
eg: ./Setup install --protocol=BSCSTRM
|
||||
|
||||
SS7: WANPIPE SS7 API sample programs. These programs
|
||||
should be used for rapid ss7 api development,
|
||||
and initial testing.
|
||||
|
||||
eg: ./Setup install --protocol=SS7
|
||||
|
||||
MPAPI: WANPIPE Multi-Protocol API Stacks
|
||||
The MPAPI includes the Wanpipe X25/LapB kernel stack.
|
||||
These programs should be used for rapid X25API
|
||||
development,and initial testing. Furhtermore the kernel
|
||||
X25API stack can run on top of MP HDLC driver or MP Frame
|
||||
Relay driver, over PRI and SEC S514/S508 ports.
|
||||
|
||||
|
||||
To compile all api sample programs:
|
||||
|
||||
1. Change directory to /etc/wanpipe/api
|
||||
2. Run 'make'
|
|
@ -0,0 +1,28 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: adccp_api
|
||||
@echo "Ok."
|
||||
|
||||
adccp_api: adccp_api.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f adccp_api
|
|
@ -0,0 +1,479 @@
|
|||
/*****************************************************************************
|
||||
* pvc_client.c X25API: PVC Client Application
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 1995-2000 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_x25.h>
|
||||
#include <linux/wanpipe_x25_kernel.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include "lib_api.h"
|
||||
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define MIN_FRM_LGTH 10
|
||||
#define MAX_FRM_LGTH 1400
|
||||
#define NO_FRMS_TO_TX 100
|
||||
|
||||
#define MAX_X25_ADDR_SIZE 16
|
||||
#define MAX_X25_DATA_SIZE 129
|
||||
#define MAX_X25_FACL_SIZE 110
|
||||
|
||||
#define TIMEOUT 10
|
||||
|
||||
unsigned char Tx_data[MIN_FRM_LGTH + sizeof(x25api_hdr_t)];
|
||||
|
||||
unsigned char Rx_data[1000];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection(void);
|
||||
void handle_socket(void);
|
||||
void setup_signal_handlers (void);
|
||||
void quit (int);
|
||||
void handle_oob_event(x25api_t* api_hdr);
|
||||
|
||||
|
||||
/* Defined global so it would only get allocated once.
|
||||
* If it was defined in MakeConnection() function it
|
||||
* would be allocated and dealocated every time we
|
||||
* run that function.
|
||||
*/
|
||||
|
||||
int sock;
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call send_socket() to transmit data
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
|
||||
proceed=init_args(argc,argv);
|
||||
if (proceed != WAN_TRUE){
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
proceed = MakeConnection();
|
||||
if( proceed == WAN_TRUE){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*/
|
||||
|
||||
int MakeConnection (void)
|
||||
{
|
||||
int len = sizeof(struct wan_sockaddr_ll);
|
||||
int err = 0;
|
||||
struct wan_sockaddr_ll sa;
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
|
||||
/* Create a new socket */
|
||||
sock = socket(AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( sock < 0 ) {
|
||||
perror("Socket");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Fill in binding information
|
||||
* before we use connect() system call
|
||||
* a socket must be binded into a
|
||||
* network interface defined in wanpipe#.conf.
|
||||
*
|
||||
* Card name must be supplied as well. In
|
||||
* this case the user supplies the name
|
||||
* eg: wanpipe1.
|
||||
*/
|
||||
sa.sll_family = AF_WANPIPE;
|
||||
sa.sll_protocol = htons(WP_LAPB_PROT);
|
||||
strcpy( sa.sll_device, if_name);
|
||||
strcpy( sa.sll_card, card_name);
|
||||
|
||||
/* Bind a sock to */
|
||||
if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) == -1){
|
||||
perror("bind");
|
||||
printf("Failed to bind socket to %s interface\n",if_name);
|
||||
close(sock);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* The sa address structure is optional. The sa
|
||||
* structure will contain a network interface name
|
||||
* on which the connection was
|
||||
* established, but we already know this. */
|
||||
|
||||
err=connect(sock,(struct sockaddr *)&sa,len);
|
||||
|
||||
if (err == 0){
|
||||
printf("Connect OK\n");
|
||||
}else{
|
||||
perror("Connect");
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************
|
||||
* handle_socket
|
||||
*
|
||||
* o Send and Receive data via socket
|
||||
* o Create a tx packet using x25api_t data type.
|
||||
* o Both the tx and rx packets contains 16 bytes headers
|
||||
* in front of the real data. It is the responsibility
|
||||
* of the applicatino to insert this 16 bytes on tx, and
|
||||
* remove the 16 bytes on rx.
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* o 16 byte Header: data structure:
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char qdm PACKED; Q/D/M bits
|
||||
* unsigned char cause PACKED; cause field
|
||||
* unsigned char diagn PACKED; diagnostics
|
||||
* unsigned char pktType PACKED;
|
||||
* unsigned short length PACKED;
|
||||
* unsigned char result PACKED;
|
||||
* unsigned short lcn PACKED;
|
||||
* char reserved[7] PACKED;
|
||||
* }x25api_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* x25api_hdr_t hdr PACKED;
|
||||
* char data[X25_MAX_DATA] PACKED;
|
||||
* }x25api_t;
|
||||
*
|
||||
* TX DATA:
|
||||
* --------
|
||||
* Each tx data packet must contain the above 16 byte header!
|
||||
*
|
||||
* Only relevant byte in the 16 byte tx header, is the
|
||||
* QDM byte. The driver will look at this byte to determine
|
||||
* if the Mbit (more data bit) should be set.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* RX DATA:
|
||||
* --------
|
||||
* Each rx data will contain the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte rx header, are the
|
||||
* LCN and QDM bytes.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* LCN = contains the lcn number for the rx frame.
|
||||
*
|
||||
* OOB DATA:
|
||||
* ---------
|
||||
* The OOB (out of band) data is used by the driver to
|
||||
* indicate x25 events for the active channel:
|
||||
* clear call, or restarts.
|
||||
*
|
||||
* Each OOB packet contains the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte oob header, are the
|
||||
* pktType, cause and diagn bytes.
|
||||
*
|
||||
* pktType = event type (ex Clear Call, Restart ...)
|
||||
* cause = x25 cause of the event
|
||||
* diagn = x25 diagnostic information used to determine
|
||||
* the cause of the event.
|
||||
*
|
||||
* Upon receiving an event, the sock should be considered
|
||||
* DEAD!!! Meaning it must be closed using the close()
|
||||
* function.
|
||||
*/
|
||||
|
||||
void handle_socket(void)
|
||||
{
|
||||
unsigned int Tx_count=0;
|
||||
unsigned short Tx_lgth,timeout=0;
|
||||
int err=0, i, Rx_count=0;
|
||||
struct timeval tv;
|
||||
x25api_t* api_tx_el;
|
||||
fd_set writeset,readset,oobset;
|
||||
|
||||
Rx_count = 0;
|
||||
Tx_count = 0;
|
||||
Tx_lgth = tx_size;
|
||||
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 5;
|
||||
|
||||
api_tx_el = (x25api_t *)Tx_data;
|
||||
|
||||
memset(&api_tx_el->hdr,0,sizeof(x25api_hdr_t));
|
||||
|
||||
/* Fill in the packet data */
|
||||
for (i=0; i<Tx_lgth ; i++){
|
||||
api_tx_el->data[i] = (unsigned char) i;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_ZERO(&writeset);
|
||||
|
||||
FD_SET(sock,&readset);
|
||||
FD_SET(sock,&oobset);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock,&writeset);
|
||||
}
|
||||
|
||||
/* This must be within the loop */
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = TIMEOUT;
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if already queued packet
|
||||
* cannot be sent
|
||||
*/
|
||||
|
||||
if((err=select(sock + 1,&readset, &writeset, &oobset, &tv))){
|
||||
|
||||
if (FD_ISSET(sock,&oobset)){
|
||||
|
||||
/* The OOB Message will indicate that an
|
||||
* asynchronous event occured. The applicaton
|
||||
* must stop everything and check the state of
|
||||
* the link. Since link might
|
||||
* have gone down */
|
||||
|
||||
/* In this example I just exit. A real
|
||||
* application would check the state of the
|
||||
* sock first by reading the header information.
|
||||
*/
|
||||
|
||||
/* If we fail to read the OOB message, we can
|
||||
* assume that the link is down. Thus, close
|
||||
* the socket and continue */
|
||||
|
||||
err = recv(sock, Rx_data, sizeof(Rx_data), MSG_OOB);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
|
||||
/* Link disconnected */
|
||||
printf("Failed to receive OOB %i\n", err);
|
||||
break;
|
||||
}else{
|
||||
api_tx_el = (x25api_t *)Rx_data;
|
||||
handle_oob_event(api_tx_el);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&readset)){
|
||||
|
||||
err = recv(sock, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
printf("Failed to rcv %i , %i\n", Rx_count, err);
|
||||
exit(1);
|
||||
|
||||
}else if (read_enable){
|
||||
|
||||
/* Every received packet comes with the 16
|
||||
* bytes of header which driver adds on.
|
||||
* Header is structured as x25api_hdr_t.
|
||||
* (same as above)
|
||||
*/
|
||||
|
||||
x25api_hdr_t *api_data =
|
||||
(x25api_hdr_t *)Rx_data;
|
||||
|
||||
if (api_data->qdm & 0x01){
|
||||
/* More bit is set, thus
|
||||
* handle it accordingly */
|
||||
}
|
||||
|
||||
if (verbose){
|
||||
printf("\tReceive OK, size: %i, qdm %x,"
|
||||
"cause %x, diagn %x, cnt: %i\n",
|
||||
err, api_data->qdm,
|
||||
api_data->cause,
|
||||
api_data->diagn, ++Rx_count);
|
||||
}else{
|
||||
putchar('R');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&writeset)){
|
||||
|
||||
err = send(sock, Tx_data, Tx_lgth +
|
||||
sizeof(x25api_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err > 0){
|
||||
++Tx_count;
|
||||
|
||||
if (verbose){
|
||||
printf("Packet Sent %i\n",Tx_count);
|
||||
}else{
|
||||
putchar('T');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (tx_delay){
|
||||
sleep(tx_delay);
|
||||
}
|
||||
|
||||
if (tx_cnt && Tx_count == tx_cnt){
|
||||
break;
|
||||
}
|
||||
|
||||
timeout=0;
|
||||
}else{
|
||||
if (err == 0){
|
||||
if (++timeout == 5){
|
||||
printf("Sock timeout exceeded MAXIMUM\n");
|
||||
sleep(10);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
printf("Sock timeout try again !!!\n");
|
||||
}else{
|
||||
printf("Error in Select !!!\n");
|
||||
break;
|
||||
}
|
||||
}//if select
|
||||
fflush(stdout);
|
||||
}//for
|
||||
|
||||
close(sock);
|
||||
}
|
||||
|
||||
void handle_oob_event(x25api_t* api_hdr)
|
||||
{
|
||||
|
||||
switch (api_hdr->hdr.pktType){
|
||||
|
||||
case ASE_RESET_RQST:
|
||||
printf("SockId=%i : OOB : Rx Reset Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
/* NOTE: we don't have to close the socket,
|
||||
* since the reset doesn't clear the call
|
||||
* however, it means that there is something really
|
||||
* wrong and that data has been lost */
|
||||
return;
|
||||
|
||||
|
||||
case ASE_CLEAR_RQST:
|
||||
printf("SockId=%i : OOB : Rx Clear Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
|
||||
case ASE_RESTART_RQST:
|
||||
printf("SockId=%i : OOB : Rx Restart Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
case ASE_INTERRUPT:
|
||||
printf("SockId=%i : OOB : Rx Interrupt Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("SockId=%i : OOB : Rx Type=0x%02X : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.pktType,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
VPATH = $(SYSINC)
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: aft_api aft_api_rbs
|
||||
@echo "Ok."
|
||||
|
||||
aft_api: aft_api.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
aft_api_rbs: aft_api_rbs.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f aft_api
|
||||
rm -f aft_api_rbs
|
|
@ -0,0 +1,36 @@
|
|||
AFT API Package
|
||||
=================
|
||||
|
||||
Author: Nenad Corbic
|
||||
Date: Apr 12, 2004
|
||||
|
||||
|
||||
|
||||
The aft package contains the sample client and server
|
||||
program that should be used in user application
|
||||
development.
|
||||
|
||||
|
||||
Contents of the API Package
|
||||
---------------------------
|
||||
|
||||
1) aft_api.c : Client application that sends and receives data.
|
||||
|
||||
Eg: Enable Rx and Tx: Tx 10 frames 100 bytes
|
||||
|
||||
aft_api -i wp1aft -c wanpipe1 -r -w -txsize 100 -txcnt 10 -verbose
|
||||
|
||||
Eg: Rx Only
|
||||
|
||||
aft_api -i wp1aft -c wanpipe1 -r -verbose
|
||||
|
||||
|
||||
Legend:
|
||||
|
||||
wp1aft: is a network interface specified in
|
||||
wanpipe config file.
|
||||
(Change to reflect your configuration)
|
||||
|
||||
wanpipe1: is the sangoma adapter card specified
|
||||
in wanpipe config file.
|
||||
(Change to reflect your configuration)
|
|
@ -0,0 +1,487 @@
|
|||
/*****************************************************************************
|
||||
* aft_api.c AFT T1/E1: HDLC API Sample Code
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/wanpipe_defines.h>
|
||||
#include <linux/wanpipe_cfg.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_xilinx.h>
|
||||
#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(api_tx_hdr_t)];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection(void);
|
||||
void handle_socket( void);
|
||||
void sig_end(int sigid);
|
||||
|
||||
int sock;
|
||||
FILE *tx_fd=NULL,*rx_fd=NULL;
|
||||
|
||||
/***************************************************
|
||||
* 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( WAN_FALSE );
|
||||
} /* if */
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int customer_id;
|
||||
int err = ioctl(sock,SIOC_AFT_CUSTOMER_ID,&customer_id);
|
||||
if (err){
|
||||
perror("Customer ID: ");
|
||||
}else{
|
||||
printf("Customer ID 0x%X\n",customer_id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
printf("Socket bound to %s\n\n",if_name);
|
||||
|
||||
return( WAN_TRUE );
|
||||
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* 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 {
|
||||
* unsigned char error_flag;
|
||||
* unsigned short time_stamp;
|
||||
* unsigned char reserved[13];
|
||||
* } api_rx_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* api_rx_hdr_t api_rx_hdr;
|
||||
* unsigned char data[1];
|
||||
* } api_rx_element_t;
|
||||
*
|
||||
*/
|
||||
|
||||
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 rlen;
|
||||
int stream_sync=0;
|
||||
|
||||
Rx_count = 0;
|
||||
Tx_count = 0;
|
||||
Tx_length = tx_size;
|
||||
|
||||
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(api_tx_hdr_t));
|
||||
|
||||
/* If rx file is specified, open
|
||||
* it and prepare it for writing */
|
||||
if (files_used & RX_FILE_USED){
|
||||
rx_fd=fopen(rx_file,"wb");
|
||||
if (!rx_fd){
|
||||
printf("Failed to open file %s\n",rx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
printf("Opening %s rx file\n",rx_file);
|
||||
}
|
||||
|
||||
/* 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 = (api_tx_element_t*)&Tx_data[0];
|
||||
|
||||
if (files_used & TX_FILE_USED){
|
||||
|
||||
/* TX file is used to transmit data */
|
||||
|
||||
tx_fd=fopen(tx_file,"rb");
|
||||
if (!tx_fd){
|
||||
printf("Failed to open file %s\n",tx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Opening %s tx file\n",rx_file);
|
||||
|
||||
rlen=fread((void*)&Tx_data[sizeof(api_tx_hdr_t)],
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
if (!rlen){
|
||||
printf("%s: File empty!\n",
|
||||
tx_file);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
|
||||
/* Create a Tx packet based on user info, or
|
||||
* by deafult incrementing number starting from 0 */
|
||||
for (i=0;i<Tx_length;i++){
|
||||
if (tx_data == -1){
|
||||
api_tx_el->data[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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Main Rx Tx OOB routine */
|
||||
for(;;) {
|
||||
|
||||
/* Initialize all select() descriptors */
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock,&write);
|
||||
}
|
||||
|
||||
/* Select will block, until:
|
||||
* 1: OOB event, link level change
|
||||
* 2: Rx data available
|
||||
* 3: Interface able to Tx */
|
||||
|
||||
if(select(sock + 1,&ready, &write, &oob, NULL)){
|
||||
|
||||
fflush(stdout);
|
||||
if (FD_ISSET(sock,&oob)){
|
||||
|
||||
/* An OOB event is pending, usually indicating
|
||||
* a link level change */
|
||||
|
||||
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 CMD Exiting\n");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&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
|
||||
*/
|
||||
err = recv(sock, Rx_data, MAX_RX_DATA, 0);
|
||||
|
||||
if (!read_enable){
|
||||
goto bitstrm_skip_read;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if(Rx_lgth<=0) {
|
||||
printf("\nShort frame received (%d)\n",
|
||||
Rx_lgth);
|
||||
return;
|
||||
}
|
||||
|
||||
if (api_rx_el->api_rx_hdr.error_flag){
|
||||
printf("Data: ");
|
||||
for(i=0;i<20; i ++) {
|
||||
printf("0x%02X ", Rx_data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (api_rx_el->api_rx_hdr.error_flag & (1<<WP_FIFO_ERROR_BIT)){
|
||||
printf("\nPacket with fifo overflow err=0x%X len=%i\n",
|
||||
api_rx_el->api_rx_hdr.error_flag,Rx_lgth);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (api_rx_el->api_rx_hdr.error_flag & (1<<WP_CRC_ERROR_BIT)){
|
||||
printf("\nPacket with invalid crc! err=0x%X len=%i\n",
|
||||
api_rx_el->api_rx_hdr.error_flag,Rx_lgth);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (api_rx_el->api_rx_hdr.error_flag & (1<<WP_ABORT_ERROR_BIT)){
|
||||
printf("\nPacket with abort! err=0x%X len=%i\n",
|
||||
api_rx_el->api_rx_hdr.error_flag,Rx_lgth);
|
||||
continue;
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
if ((files_used & RX_FILE_USED) && rx_fd){
|
||||
fwrite((void*)&Rx_data[sizeof(api_rx_hdr_t)],
|
||||
sizeof(char),
|
||||
Rx_lgth,
|
||||
rx_fd);
|
||||
}
|
||||
|
||||
++Rx_count;
|
||||
|
||||
if (verbose){
|
||||
printf("Received %i Olen=%i Length = %i\n",
|
||||
Rx_count, err,Rx_lgth);
|
||||
#if 1
|
||||
printf("Data: ");
|
||||
for(i=0;i<Rx_lgth; i ++) {
|
||||
printf("0x%02X ", api_rx_el->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
}else{
|
||||
//putchar('R');
|
||||
}
|
||||
|
||||
if (rx_cnt > 0 && Rx_count >= rx_cnt){
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
bitstrm_skip_read:
|
||||
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock,&write)){
|
||||
|
||||
err = send(sock,Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0);
|
||||
|
||||
if (err <= 0){
|
||||
if (errno == EBUSY){
|
||||
if (verbose){
|
||||
printf("Sock busy try again!\n");
|
||||
}
|
||||
/* 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("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 ((files_used & TX_FILE_USED) && tx_fd){
|
||||
rlen=fread((void*)&Tx_data[sizeof(api_tx_hdr_t)],
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
if (!rlen){
|
||||
printf("\nTx of file %s is done!\n",
|
||||
tx_file);
|
||||
break;
|
||||
}
|
||||
if (Tx_length != rlen){
|
||||
Tx_length = rlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
close (sock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call handle_socket() 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);
|
||||
|
||||
proceed = MakeConnection();
|
||||
if( proceed == WAN_TRUE){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
void sig_end(int sigid)
|
||||
{
|
||||
|
||||
printf("Got Signal %i\n",sigid);
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
if (sock){
|
||||
close (sock);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,475 @@
|
|||
/*****************************************************************************
|
||||
* aft_api.c AFT T1/E1: HDLC API Sample Code
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_xilinx.h>
|
||||
#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(api_tx_hdr_t)];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection(void);
|
||||
void handle_socket( void);
|
||||
void sig_end(int sigid);
|
||||
|
||||
int sock;
|
||||
FILE *tx_fd=NULL,*rx_fd=NULL;
|
||||
|
||||
/***************************************************
|
||||
* 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( WAN_FALSE );
|
||||
} /* if */
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int customer_id;
|
||||
int err = ioctl(sock,SIOC_AFT_CUSTOMER_ID,&customer_id);
|
||||
if (err){
|
||||
perror("Customer ID: ");
|
||||
}else{
|
||||
printf("Customer ID 0x%X\n",customer_id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
printf("Socket bound to %s\n\n",if_name);
|
||||
|
||||
return( WAN_TRUE );
|
||||
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* 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 {
|
||||
* unsigned char error_flag;
|
||||
* unsigned short time_stamp;
|
||||
* unsigned char reserved[13];
|
||||
* } api_rx_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* api_rx_hdr_t api_rx_hdr;
|
||||
* unsigned char data[1];
|
||||
* } api_rx_element_t;
|
||||
*
|
||||
*/
|
||||
|
||||
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 rlen;
|
||||
|
||||
Rx_count = 0;
|
||||
Tx_count = 0;
|
||||
Tx_length = tx_size;
|
||||
|
||||
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(api_tx_hdr_t));
|
||||
|
||||
/* If rx file is specified, open
|
||||
* it and prepare it for writing */
|
||||
if (files_used & RX_FILE_USED){
|
||||
rx_fd=fopen(rx_file,"wb");
|
||||
if (!rx_fd){
|
||||
printf("Failed to open file %s\n",rx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
printf("Opening %s rx file\n",rx_file);
|
||||
}
|
||||
|
||||
/* 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 = (api_tx_element_t*)&Tx_data[0];
|
||||
|
||||
if (files_used & TX_FILE_USED){
|
||||
|
||||
/* TX file is used to transmit data */
|
||||
|
||||
tx_fd=fopen(tx_file,"rb");
|
||||
if (!tx_fd){
|
||||
printf("Failed to open file %s\n",tx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Opening %s tx file\n",rx_file);
|
||||
|
||||
rlen=fread((void*)&Tx_data[sizeof(api_tx_hdr_t)],
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
if (!rlen){
|
||||
printf("%s: File empty!\n",
|
||||
tx_file);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
|
||||
/* Create a Tx packet based on user info, or
|
||||
* by deafult incrementing number starting from 0 */
|
||||
for (i=0;i<Tx_length;i++){
|
||||
if (tx_data == -1){
|
||||
api_tx_el->data[i] = (unsigned char)i;
|
||||
}else{
|
||||
api_tx_el->data[i] = (unsigned char)tx_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Main Rx Tx OOB routine */
|
||||
for(;;) {
|
||||
|
||||
/* Initialize all select() descriptors */
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock,&write);
|
||||
}
|
||||
|
||||
/* Select will block, until:
|
||||
* 1: OOB event, link level change
|
||||
* 2: Rx data available
|
||||
* 3: Interface able to Tx */
|
||||
|
||||
if(select(sock + 1,&ready, &write, &oob, NULL)){
|
||||
|
||||
fflush(stdout);
|
||||
if (FD_ISSET(sock,&oob)){
|
||||
|
||||
/* An OOB event is pending, usually indicating
|
||||
* a link level change */
|
||||
|
||||
err = recv(sock, Rx_data, MAX_RX_DATA, MSG_OOB);
|
||||
api_rx_el = (api_rx_element_t*)&Rx_data[0];
|
||||
|
||||
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;
|
||||
}else{
|
||||
printf("GOT OOB EXCEPTION: Timeslot=%i Status=0x%X: A=%d B=%d C=%d D=%d\n",
|
||||
api_rx_el->api_rx_hdr.channel,api_rx_el->data[0],
|
||||
api_rx_el->data[0]&WAN_RBS_SIG_A?1:0,
|
||||
api_rx_el->data[0]&WAN_RBS_SIG_B?1:0,
|
||||
api_rx_el->data[0]&WAN_RBS_SIG_C?1:0,
|
||||
api_rx_el->data[0]&WAN_RBS_SIG_D?1:0);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&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
|
||||
*/
|
||||
err = recv(sock, Rx_data, MAX_RX_DATA, 0);
|
||||
|
||||
if (!read_enable){
|
||||
goto bitstrm_skip_read;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if(Rx_lgth<=0) {
|
||||
printf("\nShort frame received (%d)\n",
|
||||
Rx_lgth);
|
||||
return;
|
||||
}
|
||||
|
||||
if (api_rx_el->api_rx_hdr.error_flag){
|
||||
printf("Data: ");
|
||||
for(i=0;i<20; i ++) {
|
||||
printf("0x%02X ", Rx_data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (api_rx_el->api_rx_hdr.error_flag & (1<<WP_FIFO_ERROR_BIT)){
|
||||
printf("\nPacket with fifo overflow err=0x%X len=%i\n",
|
||||
api_rx_el->api_rx_hdr.error_flag,Rx_lgth);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (api_rx_el->api_rx_hdr.error_flag & (1<<WP_CRC_ERROR_BIT)){
|
||||
printf("\nPacket with invalid crc! err=0x%X len=%i\n",
|
||||
api_rx_el->api_rx_hdr.error_flag,Rx_lgth);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (api_rx_el->api_rx_hdr.error_flag & (1<<WP_ABORT_ERROR_BIT)){
|
||||
printf("\nPacket with abort! err=0x%X len=%i\n",
|
||||
api_rx_el->api_rx_hdr.error_flag,Rx_lgth);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if ((files_used & RX_FILE_USED) && rx_fd){
|
||||
fwrite((void*)&Rx_data[sizeof(api_rx_hdr_t)],
|
||||
sizeof(char),
|
||||
Rx_lgth,
|
||||
rx_fd);
|
||||
}
|
||||
|
||||
++Rx_count;
|
||||
|
||||
if (verbose){
|
||||
printf("Received %i Olen=%i Length = %i\n",
|
||||
Rx_count, err,Rx_lgth);
|
||||
#if 1
|
||||
printf("Data: ");
|
||||
for(i=0;i<Rx_lgth; i ++) {
|
||||
printf("0x%02X ", api_rx_el->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
}else{
|
||||
//putchar('R');
|
||||
}
|
||||
|
||||
if (rx_cnt > 0 && Rx_count >= rx_cnt){
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
bitstrm_skip_read:
|
||||
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock,&write)){
|
||||
|
||||
err = send(sock,Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0);
|
||||
|
||||
if (err <= 0){
|
||||
if (errno == EBUSY){
|
||||
if (verbose){
|
||||
printf("Sock busy try again!\n");
|
||||
}
|
||||
/* 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("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 ((files_used & TX_FILE_USED) && tx_fd){
|
||||
rlen=fread((void*)&Tx_data[sizeof(api_tx_hdr_t)],
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
if (!rlen){
|
||||
printf("\nTx of file %s is done!\n",
|
||||
tx_file);
|
||||
break;
|
||||
}
|
||||
if (Tx_length != rlen){
|
||||
Tx_length = rlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
close (sock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call handle_socket() 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);
|
||||
|
||||
proceed = MakeConnection();
|
||||
if( proceed == WAN_TRUE){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
void sig_end(int sigid)
|
||||
{
|
||||
|
||||
printf("Got Signal %i\n",sigid);
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
if (sock){
|
||||
close (sock);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
VPATH = $(SYSINC)
|
||||
APIINC = /usr/src/linux/include
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: bsc_cmd \
|
||||
bsc_api
|
||||
@echo "Ok."
|
||||
|
||||
bsc_cmd: bsc_cmd.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
bsc_api: bsc_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
|
||||
clean:
|
||||
rm -f bsc_cmd
|
||||
rm -f bsc_api
|
|
@ -0,0 +1,29 @@
|
|||
BISYCN API Package
|
||||
==================
|
||||
|
||||
Author: Nenad Corbic
|
||||
Date: Nov 10, 2001
|
||||
|
||||
|
||||
|
||||
The bisync package contains the sample client and server
|
||||
program that should be used in user application
|
||||
development.
|
||||
|
||||
|
||||
Contents of the API Package
|
||||
---------------------------
|
||||
|
||||
1) bsc_api.c : A sample API utility, that will send and receive
|
||||
data packets across a bisync line. This program
|
||||
should be used as a starting point in developing
|
||||
a real-world bisycn application.
|
||||
|
||||
2) bsc_cmd.c : Interactive application, where user can
|
||||
execute all bisycn commands. This application
|
||||
should only be used as a bisync tester.
|
||||
|
||||
3) /usr/share/doc/wanpipe/bisync.pdf:
|
||||
BiSync documentation.
|
||||
Explanation of each BiSync command.
|
||||
|
|
@ -0,0 +1,434 @@
|
|||
/*****************************************************************************
|
||||
* bsc_api.c BiSync API: Receive Module
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 bsc_api.c utility will bind to a socket to a bsc 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.
|
||||
*
|
||||
* Command Documentation:
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_bscmp.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define LGTH_CRC_BYTES 2
|
||||
#define MAX_TX_DATA 10 /* Size of tx data */
|
||||
#define MAX_FRAMES 5000 /* Number of frames to transmit */
|
||||
|
||||
#define WRITE 1
|
||||
|
||||
/*===================================================
|
||||
* Golobal data
|
||||
*==================================================*/
|
||||
|
||||
unsigned short Rx_lgth;
|
||||
unsigned char Rx_data[16000];
|
||||
unsigned char Tx_data[MAX_TX_DATA + sizeof(api_tx_hdr_t)];
|
||||
int sock;
|
||||
|
||||
/* Structure used to execute BiSync commands */
|
||||
BSC_MAILBOX_STRUCT mbox;
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Function Prototypes
|
||||
*==================================================*/
|
||||
int MakeConnection(char *, char *);
|
||||
void process_con( void);
|
||||
|
||||
|
||||
|
||||
/*===================================================
|
||||
* DoCommand
|
||||
*
|
||||
* Execute a BiSync command directly on the
|
||||
* sangoma adapter. Refer to the
|
||||
* /usr/share/doc/wanpipe/bisync.pdf for the
|
||||
* list and explanation of BiSync commands.
|
||||
*
|
||||
*/
|
||||
|
||||
int DoCommand (BSC_MAILBOX_STRUCT *mbox)
|
||||
{
|
||||
return ioctl(sock, SIOC_WANPIPE_BSC_CMD, mbox);
|
||||
}
|
||||
|
||||
|
||||
/*===================================================
|
||||
* ConfigBisync
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
int ConfigBisync(BSC_MAILBOX_STRUCT *mbox)
|
||||
{
|
||||
int err;
|
||||
BSC_CONFIG_STRUCT cfg = { 0, //line_speed_number
|
||||
500, //max_data_frame_size
|
||||
1, //secondary_station
|
||||
5, //num_consec_PAD_eof
|
||||
2, //num_add_lead_SYN
|
||||
0, //1 //conversational_mode
|
||||
0, //pp_dial_up_operation
|
||||
0, //switched_CTS_RTS
|
||||
1, //EBCDIC_encoding
|
||||
1, //auto_open
|
||||
0, //misc_bits
|
||||
1, //0 //protocol_options1
|
||||
0, //protocol_options2
|
||||
0, //reserved_pp
|
||||
10, //max_retransmissions
|
||||
10, //fast_poll_retries
|
||||
3, //TTD_retries
|
||||
10, //restart_timer
|
||||
1000, //pp_slow_restart_timer
|
||||
50, //TTD_timer
|
||||
100, //pp_delay_between_EOT_ENQ
|
||||
50, //response_timer
|
||||
100, //rx_data_timer
|
||||
40, //NAK_retrans_delay_timer
|
||||
50, //wait_CTS_timer
|
||||
5, //mp_max_consec_ETX
|
||||
0x7f, //mp_general_poll_address
|
||||
2000, //sec_poll_timeout
|
||||
20, //pri_poll_skips_inactive
|
||||
3, //sec_additional_stn_send_gpoll
|
||||
10, //pri_select_retries
|
||||
0, //mp_multipoint_options
|
||||
1 //reserved 0=RS232 1=V35
|
||||
};
|
||||
|
||||
|
||||
memset(mbox,0,MBOX_HEADER_SZ);
|
||||
|
||||
mbox->command= CLOSE_LINK;
|
||||
DoCommand(mbox);
|
||||
|
||||
mbox->buffer_length = sizeof(BSC_CONFIG_STRUCT);
|
||||
mbox->command = SET_CONFIGURATION;
|
||||
memcpy(mbox->data,&cfg,sizeof(BSC_CONFIG_STRUCT));
|
||||
|
||||
if ((err=DoCommand(mbox)) != 0){
|
||||
printf("Failed to configure bisync station!\n");
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*===================================================
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*==================================================*/
|
||||
|
||||
int MakeConnection(char *r_name, char *i_name )
|
||||
{
|
||||
struct wan_sockaddr_ll sa;
|
||||
int err;
|
||||
|
||||
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", r_name, i_name);
|
||||
|
||||
strcpy( sa.sll_device, i_name);
|
||||
strcpy( sa.sll_card, r_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",i_name);
|
||||
exit(0);
|
||||
}
|
||||
printf("Socket bound to %s\n\n",i_name);
|
||||
|
||||
memset(&mbox,0,sizeof(mbox));
|
||||
err=ConfigBisync(&mbox);
|
||||
if (err){
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
memset(&mbox,0,sizeof(mbox));
|
||||
|
||||
/* The user should add as many station as needed
|
||||
* at this point */
|
||||
mbox.command=ADD_STATION;
|
||||
mbox.buffer_length=3;
|
||||
mbox.poll_address=0x40;
|
||||
mbox.select_address=0x60;
|
||||
mbox.device_address=0xc1;
|
||||
mbox.data[0]=0;
|
||||
mbox.data[1]=0;
|
||||
mbox.data[2]=0x80;
|
||||
|
||||
if (DoCommand(&mbox) != 0){
|
||||
printf("Failed to add station!\n");
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
|
||||
}
|
||||
|
||||
/*===========================================================
|
||||
* process_con
|
||||
*
|
||||
* 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 station PACKED;
|
||||
* unsigned char reserved[15] PACKED;
|
||||
* } api_rx_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* api_rx_hdr_t api_rx_hdr PACKED;
|
||||
* void * data PACKED;
|
||||
* } api_rx_element_t;
|
||||
*
|
||||
* station:
|
||||
* bisync station that received a packet
|
||||
*
|
||||
* TX_DATA:
|
||||
* --------
|
||||
* Each tx data packet MUST contain a 16 byte header!
|
||||
*
|
||||
* o Tx 16 byte data structure
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char station PACKED;
|
||||
* unsigned char misc_tx_rx_bits PACKED;
|
||||
* unsigned char reserved[14] PACKED;
|
||||
* } api_tx_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* api_tx_hdr_t api_tx_hdr PACKED;
|
||||
* void * data PACKED;
|
||||
* } api_tx_element_t;
|
||||
*
|
||||
* station:
|
||||
*
|
||||
* The station filed must be used to indicate
|
||||
* the station number on which the packet
|
||||
* should be transmitted.
|
||||
*
|
||||
* misc_tx_rx_bits:
|
||||
* The misc_tx_rx_bits can be used to control
|
||||
* the WRITE command.
|
||||
*
|
||||
* Refer to the /usr/share/doc/wanpipe/bisync.pdf
|
||||
*/
|
||||
|
||||
void process_con(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;
|
||||
int err,i;
|
||||
unsigned char *data;
|
||||
int tx_ok=0;
|
||||
|
||||
Rx_count = 0;
|
||||
Tx_count = 0;
|
||||
Tx_length = MAX_TX_DATA;
|
||||
|
||||
/* If running HDLC_STREAMING then the received CRC bytes
|
||||
* will be passed to the application as part of the
|
||||
* received data. The CRC bytes will be appended as the
|
||||
* last two bytes in the rx packet.
|
||||
*/
|
||||
|
||||
memset(&Tx_data[0],0,MAX_TX_DATA + sizeof(api_tx_hdr_t));
|
||||
|
||||
|
||||
/* Initialize the tx packet. The 16 byte header must
|
||||
* be inserted before tx data. */
|
||||
api_tx_el = (api_tx_element_t*)&Tx_data[0];
|
||||
data = (unsigned char *)&api_tx_el->data;
|
||||
|
||||
/* Send on a particular BiSync station */
|
||||
api_tx_el->api_tx_hdr.station = 0;
|
||||
api_tx_el->api_tx_hdr.misc_tx_rx_bits=0;
|
||||
|
||||
|
||||
/* Create a data packet */
|
||||
for (i=0;i<Tx_length;i++){
|
||||
data[i] = (unsigned char)1;
|
||||
}
|
||||
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_SET(sock,&ready);
|
||||
#ifdef WRITE
|
||||
if (tx_ok)
|
||||
FD_SET(sock,&write);
|
||||
#endif
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active sockets.
|
||||
*/
|
||||
|
||||
if(select(sock + 1,&ready, &write, NULL, NULL)){
|
||||
|
||||
/* Check for rx packets */
|
||||
if (FD_ISSET(sock,&ready)){
|
||||
|
||||
err = recv(sock, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err indicates bytes received */
|
||||
if(err > 0) {
|
||||
|
||||
/* Rx packet recevied OK
|
||||
* Each rx packet will contain 16 bytes of
|
||||
* rx header, that must be removed. The
|
||||
* first byte of the 16 byte header will
|
||||
* indicate an error condition.
|
||||
*/
|
||||
|
||||
api_rx_el = (api_rx_element_t*)Rx_data;
|
||||
|
||||
/* Check the packet length, after we remove
|
||||
* the 16 bytes rx header */
|
||||
Rx_lgth = err - sizeof(api_rx_hdr_t);
|
||||
|
||||
|
||||
printf("Received packet %i, Station=%i Length = %i\n",
|
||||
++Rx_count,
|
||||
api_rx_el->api_rx_hdr.station,
|
||||
Rx_lgth);
|
||||
|
||||
/* In this example I an sending data after
|
||||
* 4 received packets */
|
||||
if (!(Rx_count%4)){
|
||||
tx_ok=1;
|
||||
}
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Check if the socket is ready to tx data */
|
||||
if (FD_ISSET(sock,&write)){
|
||||
|
||||
err = send(sock,Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0);
|
||||
|
||||
if (err > 0){
|
||||
/* Packet sent ok */
|
||||
printf("Packet sent: Sent %i : %i\n",
|
||||
err,++Tx_count);
|
||||
tx_ok=0;
|
||||
}else{
|
||||
printf("Failed to send, try again ...\n");
|
||||
/* The driver is busy, we must requeue this
|
||||
* tx packet, and try resending it again
|
||||
* later. */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Stop the program afer transmitting MAX_FRAMES */
|
||||
if (Tx_count == MAX_FRAMES)
|
||||
break;
|
||||
|
||||
} else {
|
||||
printf("\nError selecting socket\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
close (sock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call process_con() to read/write the socket
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
|
||||
if (argc != 3){
|
||||
printf("Usage: rec_wan_sock <router name> <interface name>\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
proceed = MakeConnection(argv[argc - 2], argv[argc - 1]);
|
||||
if( proceed == TRUE ){
|
||||
process_con();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
|
@ -0,0 +1,355 @@
|
|||
/*****************************************************************************
|
||||
* bsc_api.c CHDLC API: Receive Module
|
||||
*
|
||||
* Author(s): Gideon Hack & Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <linux/sdla_bscmp.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define MAX_TX_DATA 1000 /* Size of tx data */
|
||||
#define MAX_FRAMES 5000 /* Number of frames to transmit */
|
||||
|
||||
#define WRITE 1
|
||||
|
||||
/*===================================================
|
||||
* Golobal data
|
||||
*==================================================*/
|
||||
|
||||
unsigned short Rx_lgth;
|
||||
unsigned char Rx_data[16000];
|
||||
unsigned char Tx_data[MAX_TX_DATA + sizeof(api_tx_hdr_t)];
|
||||
int sock=0;
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Function Prototypes
|
||||
*==================================================*/
|
||||
int MakeConnection(char *, char *);
|
||||
void print_menu (void);
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Global Declerations
|
||||
*==================================================*/
|
||||
|
||||
#define MAX_CMD_INDEX 24
|
||||
|
||||
typedef struct {
|
||||
int offset;
|
||||
int default_val;
|
||||
char var_name[50];
|
||||
}cmd_args_t;
|
||||
|
||||
typedef struct {
|
||||
int cmd;
|
||||
char cmd_string[50];
|
||||
cmd_args_t *args;
|
||||
int length;
|
||||
}cmd_key_t;
|
||||
|
||||
|
||||
|
||||
cmd_args_t add_station[] = {
|
||||
{offsetof(BSC_MAILBOX_STRUCT,poll_address), 0xC1, "poll_address"},
|
||||
{offsetof(BSC_MAILBOX_STRUCT,select_address), 0xC1, "select_address"},
|
||||
{offsetof(BSC_MAILBOX_STRUCT,device_address), 0xC1, "device_address"},
|
||||
{(offsetof(BSC_MAILBOX_STRUCT,data)+offsetof(ADD_STATION_STRUCT,max_tx_queue)),0,"max_tx_queue"},
|
||||
{(offsetof(BSC_MAILBOX_STRUCT,data)+offsetof(ADD_STATION_STRUCT,max_rx_queue)),0,"max_rx_queue"},
|
||||
{(offsetof(BSC_MAILBOX_STRUCT,data)+offsetof(ADD_STATION_STRUCT,station_flags)),0,"station_flags"},
|
||||
{-1,-1,""},
|
||||
};
|
||||
|
||||
cmd_args_t write_data[] = {
|
||||
{offsetof(BSC_MAILBOX_STRUCT,station), 0, "station"},
|
||||
{offsetof(BSC_MAILBOX_STRUCT,misc_tx_rx_bits), 0, "misc_tx_rx_bits"},
|
||||
{-1,-1,""},
|
||||
};
|
||||
|
||||
cmd_args_t read_data[] = {
|
||||
{offsetof(BSC_MAILBOX_STRUCT,station), 0, "station"},
|
||||
{-1,-1,""},
|
||||
};
|
||||
|
||||
cmd_args_t set_modem[] = {
|
||||
{offsetof(BSC_MAILBOX_STRUCT,data),0,"DCD=bit 1, CTS=bit 2"},
|
||||
{-1,-1,""},
|
||||
};
|
||||
|
||||
|
||||
|
||||
cmd_key_t cmd_list[] = {
|
||||
{0,"EXIT",NULL},
|
||||
{SET_CONFIGURATION, "SET_CONFIGURATION",NULL},
|
||||
{READ_CONFIGURATION,"READ_CONFIGURATION",NULL},
|
||||
{ADD_STATION,"ADD_STATION",add_station,3},
|
||||
{DELETE_STATION,"DELETE_STATION",NULL},
|
||||
{DELETE_ALL_STATIONS,"DELETE_ALL_STATIONS",NULL},
|
||||
{LIST_STATIONS,"LIST_STATIONS",NULL},
|
||||
{OPEN_LINK,"OPEN_LINK",NULL},
|
||||
{CLOSE_LINK,"CLOSE_LINK",NULL},
|
||||
{LINK_STATUS,"LINK_STATUS",NULL},
|
||||
{READ_OPERATIONAL_STATISTICS,"READ_OPERATIONAL_STATISTICS",NULL},
|
||||
{READ_CODE_VERSION,"READ_CODE_VERSION",NULL},
|
||||
{SET_STATION_STATUS,"SET_STATION_STATUS",NULL},
|
||||
{SET_GENERAL_OR_SPECIFIC_POLL,"SET_GENERAL_OR_SPECIFIC_POLL",NULL},
|
||||
{READ_MODEM_STATUS,"READ_MODEM_STATUS",NULL},
|
||||
{SET_MODEM_STATUS,"SET_MODEM_STATUS",set_modem,1},
|
||||
{READ_OPERATIONAL_STATISTICS,"READ_OPERATIONAL_STATISTICS",NULL},
|
||||
{READ_COMMS_ERROR_STATISTICS,"READ_COMMS_ERROR_STATISTICS",NULL},
|
||||
{READ_BSC_ERROR_STATISTICS,"READ_BSC_ERROR_STATISTICS",NULL},
|
||||
{FLUSH_OPERATIONAL_STATISTICS,"FLUSH_OPERATIONAL_STATISTICS",NULL},
|
||||
{FLUSH_COMMS_ERROR_STATISTICS,"FLUSH_COMMS_ERROR_STATISTICS",NULL},
|
||||
{FLUSH_BSC_ERROR_STATISTICS,"FLUSH_BSC_ERROR_STATISTICS",NULL},
|
||||
{FLUSH_BSC_TEXT_BUFFERS,"FLUSH_BSC_TEXT_BUFFERS",NULL},
|
||||
{BSC_READ,"READ_DATA",read_data,0},
|
||||
{BSC_WRITE,"WRITE_DATA",write_data,10},
|
||||
};
|
||||
|
||||
static unsigned char menu[]="\n"\
|
||||
"\n" \
|
||||
" BiSync Command Menu \n" \
|
||||
" =================== \n" \
|
||||
"\n" \
|
||||
" 1. SET_CONFIGURATION 14. READ_MODEM_STATUS \n" \
|
||||
" 2. READ_CONFIGURATION 15. SET_MODEM_STATUS \n" \
|
||||
"\n" \
|
||||
" 3. ADD_STATION 16. READ_OPERATIONAL_STATISTICS\n" \
|
||||
" 4. DELETE_STATION 17. READ_COMMS_ERROR_STATISTICS\n" \
|
||||
" 5. DELETE_ALL_STATIONS 18. READ_BSC_ERROR_STATISTICS \n" \
|
||||
" 6. LIST_STATIONS \n" \
|
||||
" 19. FLUSH_OPERATIONAL_STATISTICS\n" \
|
||||
"\n" \
|
||||
" 7. OPEN_LINK 20. FLUSH_COMMS_ERROR_STATISTICS \n" \
|
||||
" 8. CLOSE_LINK 21. FLUSH_BSC_ERROR_STATISTICS \n" \
|
||||
" 22. FLUSH_BSC_TEXT_BUFFERS\n" \
|
||||
" 9. LINK_STATUS \n" \
|
||||
"10. READ_OPERATIONAL_STATISTICS 23. READ DATA \n" \
|
||||
"11. READ_CODE_VERSION 24. WRITE DATA \n" \
|
||||
"\n" \
|
||||
"12. SET_STATION_STATUS 0. Exit \n" \
|
||||
"13. SET_GENERAL_OR_SPECIFIC_POLL \n" \
|
||||
" \n" \
|
||||
" Please Select a command (1-24): ";
|
||||
|
||||
|
||||
|
||||
void print_menu (void)
|
||||
{
|
||||
|
||||
printf (menu);
|
||||
}
|
||||
|
||||
/*===================================================
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*==================================================*/
|
||||
|
||||
int MakeConnection(char *r_name, char *i_name )
|
||||
{
|
||||
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", r_name, i_name);
|
||||
|
||||
strcpy( sa.sll_device, i_name);
|
||||
strcpy( sa.sll_card, r_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",i_name);
|
||||
exit(0);
|
||||
}
|
||||
printf("Socket bound to %s\n\n",i_name);
|
||||
|
||||
return( TRUE );
|
||||
|
||||
}
|
||||
|
||||
int command_map (int cmd)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<=MAX_CMD_INDEX;i++){
|
||||
if (cmd == cmd_list[i].cmd)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int DoCommand (BSC_MAILBOX_STRUCT *mbox)
|
||||
{
|
||||
|
||||
return ioctl(sock, SIOC_WANPIPE_BSC_CMD, mbox);
|
||||
}
|
||||
|
||||
|
||||
void DisplayResults (BSC_MAILBOX_STRUCT *mbox)
|
||||
{
|
||||
int i;
|
||||
printf ("\n");
|
||||
switch (mbox->return_code){
|
||||
|
||||
case 0:
|
||||
printf("Command %s executed ok!\n",
|
||||
cmd_list[command_map(mbox->command)].cmd_string);
|
||||
|
||||
if (mbox->buffer_length){
|
||||
printf("Command Data: \n");
|
||||
for (i=0;i<mbox->buffer_length;i++){
|
||||
printf ("0x%x ",mbox->data[i]);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("Command %s failed!\n",
|
||||
cmd_list[command_map(mbox->command)].cmd_string);
|
||||
}
|
||||
}
|
||||
|
||||
void mypause(void)
|
||||
{
|
||||
printf("\nPlease press any key to continue...");
|
||||
fflush(stdout);
|
||||
|
||||
getchar();
|
||||
getchar();
|
||||
//system("clear");
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call process_con() to read/write the socket
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
int command;
|
||||
int i;
|
||||
char input[100];
|
||||
BSC_MAILBOX_STRUCT mbox;
|
||||
|
||||
if (argc != 3){
|
||||
printf("Usage: rec_wan_sock <router name> <interface name>\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
proceed = MakeConnection(argv[argc - 2], argv[argc - 1]);
|
||||
if( proceed == FALSE ){
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (;;){
|
||||
print_menu();
|
||||
fflush(stdout);
|
||||
scanf("%s",input);
|
||||
command=strtoul(input, NULL, 0);
|
||||
|
||||
if (command < 0 || command > MAX_CMD_INDEX){
|
||||
printf("\nIllegal Command, Try again!\n");
|
||||
mypause();
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&mbox,0,sizeof(BSC_MAILBOX_STRUCT));
|
||||
printf("\nExecuting Command: %s\n",cmd_list[command].cmd_string);
|
||||
|
||||
if (!command)
|
||||
break;
|
||||
|
||||
mbox.command = cmd_list[command].cmd;
|
||||
|
||||
if (cmd_list[command].args){
|
||||
char input[100];
|
||||
int arg_val;
|
||||
cmd_args_t *args=cmd_list[command].args;
|
||||
for (i=0;;i++){
|
||||
if (args[i].offset==-1){
|
||||
break;
|
||||
}
|
||||
if (args[i].default_val==-1)
|
||||
break;
|
||||
|
||||
printf("%s: ",args[i].var_name);
|
||||
scanf("%s",input);
|
||||
arg_val=strtoul(input, NULL, 0);
|
||||
*((unsigned char*)&mbox+args[i].offset)=(unsigned char)arg_val;
|
||||
}
|
||||
mbox.buffer_length=cmd_list[command].length;
|
||||
if (mbox.command == BSC_WRITE){
|
||||
for (i=0;i<mbox.buffer_length;i++){
|
||||
mbox.data[i]=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DoCommand(&mbox) != 0){
|
||||
printf("Command Failed!\n");
|
||||
}else{
|
||||
DisplayResults(&mbox);
|
||||
}
|
||||
mypause();
|
||||
}
|
||||
|
||||
close(sock);
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
APIINC = ../include
|
||||
VPATH = $(SYSINC)
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: bscstrm_api
|
||||
@echo "Ok."
|
||||
|
||||
bscstrm_api: bscstrm_api.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
|
||||
clean:
|
||||
rm -f bscstrm_api
|
|
@ -0,0 +1,30 @@
|
|||
BISYCN STREAMING API Package
|
||||
============================
|
||||
|
||||
Author: Nenad Corbic
|
||||
Date: Mar 18, 2002
|
||||
|
||||
|
||||
This package was developed for receiving
|
||||
NASDAQ feeds. It is a vary specific project.
|
||||
If you need standard BiSync in ../Bisync
|
||||
directory.
|
||||
|
||||
The bisync streaming package contains the sample
|
||||
client and server program that should be used in
|
||||
user application development.
|
||||
|
||||
Make sure that the bisync streaming drivers
|
||||
have been specified during installation process.
|
||||
|
||||
./Setup install --protocol=BSCSTRM
|
||||
|
||||
|
||||
Contents of the API Package
|
||||
---------------------------
|
||||
|
||||
1) bscstrm_api.c : A sample API utility, that will send and receive
|
||||
data packets across a bisync line. This program
|
||||
should be used as a starting point in developing
|
||||
a real-world bisycn application.
|
||||
|
|
@ -0,0 +1,443 @@
|
|||
/*****************************************************************************
|
||||
* bscstrm_api.c BiSync Streaming API: Receive Module
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 1995-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.
|
||||
* ============================================================================
|
||||
* Description:
|
||||
*
|
||||
* The bscstrm_api.c utility will bind to a socket to a bisync 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_bscstrm.h>
|
||||
#include "lib_api.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define MAX_TX_DATA 5000 /* Size of tx data */
|
||||
#define MAX_RX_DATA MAX_TX_DATA
|
||||
|
||||
#define BSCSTRM_TX_TIMEOUT 10
|
||||
|
||||
FILE *tx_fd=NULL,*rx_fd=NULL;
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Golobal data
|
||||
*==================================================*/
|
||||
|
||||
unsigned short Rx_lgth;
|
||||
|
||||
unsigned char Rx_data[MAX_RX_DATA];
|
||||
unsigned char Tx_data[MAX_TX_DATA];
|
||||
int sock;
|
||||
|
||||
unsigned char ebcdic_pkt[]={0x32,0x32,0x32,0x2D,0xFF};
|
||||
|
||||
/*===================================================
|
||||
* 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( sa.sll_device, if_name);
|
||||
strcpy( 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 station 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;
|
||||
* unsigned char data[1] PACKED;
|
||||
* } api_rx_element_t;
|
||||
*
|
||||
* station:
|
||||
*
|
||||
* 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 station PACKED;
|
||||
* unsigned char misc_tx_rx_bits PACKED;
|
||||
* unsigned char reserved[14] PACKED;
|
||||
* } api_tx_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* api_tx_hdr_t api_tx_hdr PACKED;
|
||||
* unsigned char data[1] PACKED;
|
||||
* } api_tx_element_t;
|
||||
*
|
||||
* Currently the bisync 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 rlen;
|
||||
int ferr;
|
||||
int txfile_bytes=0;
|
||||
void *pRx_data,*pTx_data;
|
||||
|
||||
|
||||
pRx_data = (void*)&Rx_data[sizeof(api_rx_hdr_t)];
|
||||
pTx_data = (void*)&Tx_data[sizeof(api_tx_hdr_t)];
|
||||
|
||||
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);
|
||||
|
||||
memset(&Tx_data[0],0,MAX_TX_DATA);
|
||||
|
||||
if (files_used & RX_FILE_USED){
|
||||
rx_fd=fopen(rx_file,"wb");
|
||||
if (!rx_fd){
|
||||
printf("Failed to open file %s\n",rx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
printf("Opening %s rx file\n",rx_file);
|
||||
}
|
||||
|
||||
|
||||
if (files_used & TX_FILE_USED){
|
||||
|
||||
tx_fd=fopen(tx_file,"rb");
|
||||
if (!tx_fd){
|
||||
printf("Failed to open file %s\n",tx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Opening %s tx file\n",tx_file);
|
||||
|
||||
rlen=fread(pTx_data,
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
|
||||
|
||||
if (!rlen){
|
||||
printf("%s: File empty!\n",
|
||||
tx_file);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
api_tx_el = (api_tx_element_t*)&Tx_data[0];
|
||||
|
||||
for (i=0;i<Tx_length;i++){
|
||||
if (tx_data == -1){
|
||||
api_tx_el->data[i] = (unsigned char)i;
|
||||
}else{
|
||||
api_tx_el->data[i] = (unsigned char)tx_data;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hardcode packet to EBCDIC frame */
|
||||
//memcpy(api_tx_el->data,ebcdic_pkt,sizeof(ebcdic_pkt));
|
||||
//Tx_length=sizeof(ebcdic_pkt);
|
||||
}
|
||||
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock,&write);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
if(select(sock + 1,&ready, &write, &oob, NULL)){
|
||||
|
||||
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);
|
||||
|
||||
if (!read_enable){
|
||||
goto bitstrm_skip_read;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if(Rx_lgth<=0) {
|
||||
printf("\nShort frame received (%d)\n",
|
||||
Rx_lgth);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((files_used & RX_FILE_USED) && rx_fd){
|
||||
ferr=fwrite(pRx_data,
|
||||
sizeof(char),
|
||||
Rx_lgth,
|
||||
rx_fd);
|
||||
if (ferr != Rx_lgth){
|
||||
printf("Error: fwrite failed: written=%i should have %i\n",
|
||||
ferr,Rx_lgth);
|
||||
}
|
||||
}
|
||||
|
||||
++Rx_count;
|
||||
|
||||
if (verbose){
|
||||
printf("Received %i Olen=%i Length = %i\n",
|
||||
Rx_count, err,Rx_lgth);
|
||||
}else{
|
||||
putchar('R');
|
||||
}
|
||||
#if 1
|
||||
if (verbose){
|
||||
printf("Data: ");
|
||||
for(i=0;(i<Rx_lgth); i ++) {
|
||||
printf("0x%02X ", api_rx_el->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rx_cnt && rx_cnt == Rx_count){
|
||||
printf("Rxcnt %i == RxCount=%i\n",rx_cnt,Rx_count);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bitstrm_skip_read:
|
||||
if (FD_ISSET(sock,&write)){
|
||||
|
||||
err = send(sock,Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0);
|
||||
|
||||
if (err <= 0){
|
||||
if (errno == EBUSY){
|
||||
|
||||
/* Important: The user must implement
|
||||
* a delay, if the socket is busy */
|
||||
usleep(BSCSTRM_TX_TIMEOUT);
|
||||
|
||||
if (verbose){
|
||||
printf("Sock busy try again!\n");
|
||||
}
|
||||
/* 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){
|
||||
printf("Packet sent: Sent %i : %i\n",
|
||||
err,Tx_count);
|
||||
}else{
|
||||
//putchar('T');
|
||||
}
|
||||
txfile_bytes+=Tx_length;
|
||||
|
||||
if ((files_used & TX_FILE_USED) && tx_fd){
|
||||
rlen=fread(pTx_data,
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
|
||||
if (!rlen){
|
||||
printf("\nTx of file %s is done %i bytes!\n",
|
||||
tx_file,txfile_bytes);
|
||||
break;
|
||||
}
|
||||
if (Tx_length != rlen){
|
||||
Tx_length = rlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_delay){
|
||||
sleep(tx_delay);
|
||||
}
|
||||
|
||||
if (tx_cnt && Tx_count == tx_cnt && !(files_used & TX_FILE_USED)){
|
||||
write_enable=0;
|
||||
if (!rx_cnt){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
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(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
proceed = MakeConnection();
|
||||
if(proceed == WAN_TRUE){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
|
@ -0,0 +1,41 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
VPATH = $(SYSINC)
|
||||
APIINC = /usr/src/linux/include
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I ../lib -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: bitstrm_api \
|
||||
bitstrm_switch \
|
||||
bitstrm_txrx
|
||||
@echo "Ok."
|
||||
|
||||
bitstrm_api: bitstrm_api.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
bitstrm_switch: bitstrm_switch.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
bitstrm_txrx: bitstrm_txrx.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
|
||||
clean:
|
||||
rm -f bitstrm_api
|
||||
rm -f bitstrm_switch
|
||||
rm -f bitstrm_txrx
|
|
@ -0,0 +1,51 @@
|
|||
Bitstream Apps
|
||||
----------------
|
||||
|
||||
|
||||
bitstrm_switch:
|
||||
|
||||
Implements the bitstreaming switch between two
|
||||
interfaces.
|
||||
|
||||
All DS0 from first interface are transfered
|
||||
to the second interface, plus DS1 and DS2 are
|
||||
incremented by 1 and 2 respectively.
|
||||
|
||||
All DS0 from second interface are transfered
|
||||
to the first interface, plus DS3 and DS4 are
|
||||
incremented by 3 and 4 respectively.
|
||||
|
||||
Usage:
|
||||
|
||||
./bitstrm_switch -i <first if name> -c <first card name> \
|
||||
-si <second if name > -sc <second card name> -r
|
||||
|
||||
eg:
|
||||
./bitstrm_switch -i wp4bstrm1 -c wanpipe4 -si wp5bstrm1 -sc wanpipe5 -r
|
||||
|
||||
|
||||
bitstrm_txrx:
|
||||
|
||||
The bitstrm_txrx sends and receives a binary file. Furthermore,
|
||||
the rx binary file must contain numbers greater than 0x10.
|
||||
|
||||
The rx code will start receiving a binary stream once it
|
||||
sees a first character greater than 0x10. The idle character
|
||||
must be set to 0 in /etc/wanpipe/wanpipe#.conf.
|
||||
|
||||
Usage:
|
||||
|
||||
./bitstrm_txrx -i <if name> -c <card name> -r -w -rxfile <filename> \
|
||||
-txfile <filename> -txsize 1000
|
||||
|
||||
eg:
|
||||
./bitstrm_txrx -i wp1bstrm1 -c wanpipe1 -r -w -rxfile RXFILE \
|
||||
-txfile tx_ch_file.b -txsize 1000
|
||||
|
||||
Note: Create the tx_ch_file.b using the te1/bstrm_gen_file application.
|
||||
It is currently setup to create 2MB file containing all 0x10.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,479 @@
|
|||
/*****************************************************************************
|
||||
* bitstrm_api.c Bit Streaming API: Sample Module
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 2000-2003 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_bitstrm.h>
|
||||
#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];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection(void);
|
||||
void handle_socket( void);
|
||||
void sig_end(int sigid);
|
||||
void sig_usr(int sigid);
|
||||
|
||||
int sock;
|
||||
FILE *tx_fd=NULL,*rx_fd=NULL;
|
||||
|
||||
#if 0
|
||||
void check_for_zeros(unsigned char *data, int len, int cnt, int bytes);
|
||||
#endif
|
||||
|
||||
/***************************************************
|
||||
* 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( WAN_FALSE );
|
||||
} /* if */
|
||||
|
||||
printf("\nConnecting to router %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);
|
||||
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( WAN_TRUE );
|
||||
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* 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 {
|
||||
* unsigned char SIO 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;
|
||||
* unsigned char data[1] PACKED;
|
||||
* } api_rx_element_t;
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
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 rlen;
|
||||
int ferr;
|
||||
int txfile_bytes=0;
|
||||
void *pRx_data,*pTx_data;
|
||||
|
||||
pRx_data = (void*)&Rx_data[sizeof(api_rx_hdr_t)];
|
||||
pTx_data = (void*)&Tx_data[sizeof(api_tx_hdr_t)];
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
memset(&Tx_data[0],0,MAX_TX_DATA);
|
||||
|
||||
if (files_used & RX_FILE_USED){
|
||||
rx_fd=fopen(rx_file,"wb");
|
||||
if (!rx_fd){
|
||||
printf("Failed to open file %s\n",rx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
printf("Opening %s rx file\n",rx_file);
|
||||
}
|
||||
|
||||
|
||||
if (files_used & TX_FILE_USED){
|
||||
|
||||
tx_fd=fopen(tx_file,"rb");
|
||||
if (!tx_fd){
|
||||
printf("Failed to open file %s\n",tx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Opening %s tx file\n",tx_file);
|
||||
|
||||
rlen=fread(pTx_data,
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
|
||||
|
||||
if (!rlen){
|
||||
printf("%s: File empty!\n",
|
||||
tx_file);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
api_tx_el = (api_tx_element_t*)&Tx_data[0];
|
||||
|
||||
for (i=0;i<Tx_length;i++){
|
||||
if (tx_data == -1){
|
||||
api_tx_el->data[i] = (unsigned char)i;
|
||||
}else{
|
||||
api_tx_el->data[i] = (unsigned char)tx_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock,&write);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
if(select(sock + 1,&ready, &write, &oob, NULL) > 0){
|
||||
|
||||
if (FD_ISSET(sock,&oob)){
|
||||
|
||||
err = recv(sock, Rx_data, MAX_RX_DATA, MSG_OOB);
|
||||
|
||||
if(err < 0){
|
||||
printf("Failed to receive OOB cnt=%i , len=%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;
|
||||
}else{
|
||||
|
||||
api_rx_el = (api_rx_element_t*)&Rx_data[0];
|
||||
|
||||
printf("GOT OOB RBS: Channel=%i Data=0x%X\n",
|
||||
api_rx_el->api_rx_hdr.channel,
|
||||
api_rx_el->data[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&ready)){
|
||||
|
||||
err = recv(sock, Rx_data, MAX_RX_DATA, 0);
|
||||
|
||||
if (!read_enable){
|
||||
goto bitstrm_skip_read;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if(Rx_lgth<=0) {
|
||||
printf("\nShort frame received (%d)\n",
|
||||
Rx_lgth);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((files_used & RX_FILE_USED) && rx_fd){
|
||||
ferr=fwrite(pRx_data,
|
||||
sizeof(char),
|
||||
Rx_lgth,
|
||||
rx_fd);
|
||||
if (ferr != Rx_lgth){
|
||||
printf("Error: fwrite failed: written=%i should have %i\n",
|
||||
ferr,Rx_lgth);
|
||||
}
|
||||
}
|
||||
|
||||
++Rx_count;
|
||||
|
||||
if (verbose){
|
||||
printf("Received %i Olen=%i Length = %i\n",
|
||||
Rx_count, err,Rx_lgth);
|
||||
}else{
|
||||
//putchar('R');
|
||||
}
|
||||
#if 1
|
||||
|
||||
if (verbose){
|
||||
printf("Data: ");
|
||||
for(i=0;(i<Rx_lgth)&&(i<32); i ++) {
|
||||
printf("0x%02X ", api_rx_el->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (Rx_lgth != 52){
|
||||
printf("\nBAD Data: ");
|
||||
for(i=0;i<Rx_lgth; i ++) {
|
||||
printf("0x%02X ", api_rx_el->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}else{
|
||||
printf("\nData: 0x%02X\n",api_rx_el->data[0]);
|
||||
}
|
||||
#endif
|
||||
if (rx_cnt == Rx_count){
|
||||
printf("Rxcnt %i == RxCount=%i\n",rx_cnt,Rx_count);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
bitstrm_skip_read:
|
||||
|
||||
if (FD_ISSET(sock,&write)){
|
||||
|
||||
err = send(sock,Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0);
|
||||
|
||||
if (err <= 0){
|
||||
if (errno == EBUSY){
|
||||
if (verbose){
|
||||
printf("Sock busy try again!\n");
|
||||
}
|
||||
/* 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){
|
||||
printf("Packet sent: Sent %i : %i\n",
|
||||
err,Tx_count);
|
||||
}else{
|
||||
//putchar('T');
|
||||
}
|
||||
txfile_bytes+=Tx_length;
|
||||
|
||||
if ((files_used & TX_FILE_USED) && tx_fd){
|
||||
rlen=fread(pTx_data,
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
|
||||
if (!rlen){
|
||||
printf("\nTx of file %s is done %i bytes!\n",
|
||||
tx_file,txfile_bytes);
|
||||
break;
|
||||
}
|
||||
if (Tx_length != rlen){
|
||||
Tx_length = rlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_delay){
|
||||
sleep(tx_delay);
|
||||
}
|
||||
|
||||
if (tx_size && Tx_count == tx_cnt && !(files_used & TX_FILE_USED)){
|
||||
write_enable=0;
|
||||
if (!rx_cnt){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
close (sock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call handle_socket() 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(SIGUSR1,&sig_usr);
|
||||
signal(SIGINT,&sig_end);
|
||||
|
||||
proceed = MakeConnection();
|
||||
if( proceed == WAN_TRUE){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
void sig_usr(int sigid)
|
||||
{
|
||||
|
||||
unsigned char robbit=0x01;
|
||||
int err;
|
||||
err = ioctl(sock,SIOC_WRITE_RBS_SIG,&robbit);
|
||||
if (err!=0){
|
||||
perror("Ioctl Write RBS:");
|
||||
}
|
||||
|
||||
printf("Wrote Robbit data 0x%X\n",robbit);
|
||||
|
||||
#if 1
|
||||
err = ioctl(sock,SIOC_READ_RBS_SIG,&robbit);
|
||||
if (err!=0){
|
||||
perror("Ioctl Read RBS:");
|
||||
}
|
||||
|
||||
printf("Read Robbit data 0x%X\n",robbit);
|
||||
#endif
|
||||
}
|
||||
|
||||
void sig_end(int sigid)
|
||||
{
|
||||
|
||||
printf("Got Signal %i\n",sigid);
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
if (sock){
|
||||
close (sock);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void check_for_zeros(unsigned char *data, int len, int cnt, int bytes)
|
||||
{
|
||||
int i;
|
||||
int zero_cnt=0;
|
||||
|
||||
for (i=0;i<len;i++){
|
||||
if (data[i]==0){
|
||||
if (++zero_cnt>1){
|
||||
printf("\nSENDING MULTIPLE ZEROS: Cnt %i, Len %i Bytes %i\n",
|
||||
cnt,len,bytes);
|
||||
}
|
||||
}else{
|
||||
zero_cnt=0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,326 @@
|
|||
/*****************************************************************************
|
||||
* bitstrm_api.c Bit Streaming API: Sample Module
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 2000-2003 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_bitstrm.h>
|
||||
#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 Tx_data[MAX_TX_DATA];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection(int *,int*);
|
||||
void handle_socket(int sock, int sw_sock,int action);
|
||||
void sig_end(int sigid);
|
||||
|
||||
int handle_oob_msg(int sk, char *Rx_data);
|
||||
int handle_tx(int sk, char *Tx_data, int len);
|
||||
int handle_rx(int sk, char *Rx_data, int* Rx_lgth, int action);
|
||||
|
||||
/***************************************************
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*/
|
||||
|
||||
int MakeConnection(int *sock, int *sw_sock)
|
||||
{
|
||||
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( WAN_FALSE );
|
||||
} /* if */
|
||||
|
||||
*sw_sock = socket(AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( *sw_sock < 0 ) {
|
||||
perror("Socket");
|
||||
return( WAN_FALSE );
|
||||
} /* if */
|
||||
|
||||
|
||||
printf("\nSwitching Interfaces %s <---> %s\n",if_name,sw_if_name);
|
||||
|
||||
strcpy( sa.sll_device, if_name);
|
||||
strcpy( 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);
|
||||
}
|
||||
|
||||
strcpy(sa.sll_device, sw_if_name);
|
||||
strcpy(sa.sll_card, sw_card_name);
|
||||
sa.sll_protocol = htons(PVC_PROT);
|
||||
sa.sll_family=AF_WANPIPE;
|
||||
|
||||
if(bind(*sw_sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){
|
||||
perror("bind");
|
||||
printf("Failed to bind a socket to %s interface\n",sw_if_name);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("Socket bound to %s and %s\n\n",if_name,sw_if_name);
|
||||
|
||||
return (WAN_TRUE);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* 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 {
|
||||
* unsigned char SIO 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;
|
||||
* unsigned char data[1] PACKED;
|
||||
* } api_rx_element_t;
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
void handle_socket(int sock, int sw_sock, int action)
|
||||
{
|
||||
fd_set ready,oob;
|
||||
int len;
|
||||
unsigned char Rx_data[MAX_RX_DATA];
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&oob);
|
||||
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
fflush(stdout);
|
||||
if (select(sock + 1,&ready, NULL, &oob, NULL)){
|
||||
|
||||
if (FD_ISSET(sock,&oob)){
|
||||
if (handle_oob_msg(sock,Rx_data)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock,&ready)){
|
||||
if (handle_rx(sock,Rx_data,&len,action)){
|
||||
break;
|
||||
}
|
||||
|
||||
if (handle_tx(sw_sock,Rx_data,len)){
|
||||
printf("Warning: Failed to send data \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close (sock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call handle_socket() to read the socket
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
pid_t pid;
|
||||
int stat;
|
||||
int sock,sw_sock;
|
||||
|
||||
read_enable=1;
|
||||
write_enable=1;
|
||||
|
||||
proceed=init_args(argc,argv);
|
||||
if (proceed != WAN_TRUE){
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
signal(SIGINT,&sig_end);
|
||||
|
||||
proceed = MakeConnection(&sock,&sw_sock);
|
||||
if( proceed == WAN_TRUE){
|
||||
|
||||
if (!fork()){
|
||||
handle_socket(sock,sw_sock,0);
|
||||
exit(0);
|
||||
}
|
||||
if (!fork()){
|
||||
handle_socket(sw_sock,sock,1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
close(sock);
|
||||
close(sw_sock);
|
||||
|
||||
while ((pid=waitpid(-1,&stat,WUNTRACED)) > 0){
|
||||
printf("Child %d terminated\n",pid);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
void sig_end(int sigid)
|
||||
{
|
||||
|
||||
printf("Got Signal %i\n",sigid);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int handle_oob_msg(int sk, char *Rx_data)
|
||||
{
|
||||
int err = recv(sk, Rx_data, MAX_RX_DATA, MSG_OOB);
|
||||
|
||||
if (err < 0){
|
||||
printf("Failed to receive OOB %i\n",err);
|
||||
err = ioctl(sk,SIOC_WANPIPE_SOCK_STATE,0);
|
||||
printf("Sock state is %s\n",
|
||||
(err == 0) ? "CONNECTED" :
|
||||
(err == 1) ? "DISCONNECTED" :
|
||||
"CONNECTING");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("GOT OOB EXCEPTION CMD Exiting\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int handle_rx(int sk, char *Rx_data, int* Rx_lgth, int action)
|
||||
{
|
||||
api_rx_element_t* api_rx_el;
|
||||
int i,len;
|
||||
int err = recv(sk, Rx_data, MAX_RX_DATA, 0);
|
||||
|
||||
if (!read_enable){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* err indicates bytes received */
|
||||
if (err <= 0){
|
||||
printf("\nError receiving data\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
*Rx_lgth = err;
|
||||
api_rx_el = (api_rx_element_t*)&Rx_data[0];
|
||||
|
||||
/* Check the packet length */
|
||||
len = err - sizeof(api_rx_hdr_t);
|
||||
if(len<=0) {
|
||||
printf("\nShort frame received (%d)\n",
|
||||
*Rx_lgth);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(i=0; i<len; i++) {
|
||||
if (action){
|
||||
if (((i%24)+1) == 1){
|
||||
api_rx_el->data[i]+=1;
|
||||
}else if (((i%24)+1) == 2){
|
||||
api_rx_el->data[i]+=2;
|
||||
}
|
||||
}else{
|
||||
if (((i%24)+1) == 3){
|
||||
api_rx_el->data[i]+=3;
|
||||
}else if (((i%24)+1) == 4){
|
||||
api_rx_el->data[i]+=4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_tx(int sock, char *Tx_data, int len)
|
||||
{
|
||||
int err = send(sock,Tx_data, len, 0);
|
||||
|
||||
if (err <= 0){
|
||||
if (errno == EBUSY){
|
||||
printf("Sock busy try again!\n");
|
||||
return 1;
|
||||
/* 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: ");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,464 @@
|
|||
/*****************************************************************************
|
||||
* bitstrm_api.c Bit Streaming API: Sample Module
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 2000-2003 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_bitstrm.h>
|
||||
#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];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection(void);
|
||||
void handle_socket( void);
|
||||
void sig_end(int sigid);
|
||||
|
||||
int sock;
|
||||
FILE *tx_fd=NULL,*rx_fd=NULL;
|
||||
|
||||
#if 0
|
||||
void check_for_zeros(unsigned char *data, int len, int cnt, int bytes);
|
||||
#endif
|
||||
|
||||
/***************************************************
|
||||
* 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( WAN_FALSE );
|
||||
} /* if */
|
||||
|
||||
printf("\nConnecting to router %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);
|
||||
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( WAN_TRUE );
|
||||
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* 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 {
|
||||
* unsigned char SIO 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;
|
||||
* unsigned char data[1] PACKED;
|
||||
* } api_rx_element_t;
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
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 rlen;
|
||||
int ferr;
|
||||
int txfile_bytes=0;
|
||||
void *pRx_data,*pTx_data;
|
||||
int rx_start=0;
|
||||
|
||||
pRx_data = (void*)&Rx_data[sizeof(api_rx_hdr_t)];
|
||||
pTx_data = (void*)&Tx_data[sizeof(api_tx_hdr_t)];
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
memset(&Tx_data[0],0,MAX_TX_DATA);
|
||||
|
||||
if (files_used & RX_FILE_USED){
|
||||
rx_fd=fopen(rx_file,"wb");
|
||||
if (!rx_fd){
|
||||
printf("Failed to open file %s\n",rx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
printf("Opening %s rx file\n",rx_file);
|
||||
}
|
||||
|
||||
|
||||
if (files_used & TX_FILE_USED){
|
||||
|
||||
tx_fd=fopen(tx_file,"rb");
|
||||
if (!tx_fd){
|
||||
printf("Failed to open file %s\n",tx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Opening %s tx file\n",tx_file);
|
||||
|
||||
rlen=fread(pTx_data,
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
|
||||
|
||||
if (!rlen){
|
||||
printf("%s: File empty!\n",
|
||||
tx_file);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
api_tx_el = (api_tx_element_t*)&Tx_data[0];
|
||||
|
||||
for (i=0;i<Tx_length;i++){
|
||||
if (tx_data == -1){
|
||||
api_tx_el->data[i] = (unsigned char)i;
|
||||
}else{
|
||||
api_tx_el->data[i] = (unsigned char)tx_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock,&write);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
if(select(sock + 1,&ready, &write, &oob, NULL)){
|
||||
|
||||
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 CMD Exiting\n");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&ready)){
|
||||
|
||||
err = recv(sock, Rx_data, MAX_RX_DATA, 0);
|
||||
|
||||
if (!read_enable){
|
||||
goto bitstrm_skip_read;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if(Rx_lgth<=0) {
|
||||
printf("\nShort frame received (%d)\n",
|
||||
Rx_lgth);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((files_used & RX_FILE_USED) && rx_fd){
|
||||
|
||||
for(i=0;i<Rx_lgth; i ++) {
|
||||
if (api_rx_el->data[i] >= 0x10){
|
||||
if (!rx_start){
|
||||
printf("Start of Rx File %x\n",
|
||||
api_rx_el->data[i]);
|
||||
rx_start=1;
|
||||
}
|
||||
ferr=fwrite(&api_rx_el->data[i],
|
||||
sizeof(char),
|
||||
1,
|
||||
rx_fd);
|
||||
}else{
|
||||
if (rx_start){
|
||||
printf("End of Rx File %x\n",
|
||||
api_rx_el->data[i]);
|
||||
goto handle_socket_exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++Rx_count;
|
||||
|
||||
if (verbose){
|
||||
printf("Received %i Olen=%i Length = %i\n",
|
||||
Rx_count, err,Rx_lgth);
|
||||
}else{
|
||||
//putchar('R');
|
||||
}
|
||||
#if 1
|
||||
|
||||
if (verbose){
|
||||
printf("Data: ");
|
||||
for(i=0;(i<Rx_lgth)&&(i<32); i ++) {
|
||||
printf("0x%02X ", api_rx_el->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (Rx_lgth != 52){
|
||||
printf("\nBAD Data: ");
|
||||
for(i=0;i<Rx_lgth; i ++) {
|
||||
printf("0x%02X ", api_rx_el->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}else{
|
||||
printf("\nData: 0x%02X\n",api_rx_el->data[0]);
|
||||
}
|
||||
#endif
|
||||
if (rx_cnt == Rx_count){
|
||||
printf("Rxcnt %i == RxCount=%i\n",rx_cnt,Rx_count);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bitstrm_skip_read:
|
||||
|
||||
if (FD_ISSET(sock,&write)){
|
||||
|
||||
err = send(sock,Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0);
|
||||
|
||||
if (err <= 0){
|
||||
if (errno == EBUSY){
|
||||
if (verbose){
|
||||
printf("Sock busy try again!\n");
|
||||
}
|
||||
/* 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){
|
||||
printf("Packet sent: Sent %i : %i\n",
|
||||
err,Tx_count);
|
||||
}else{
|
||||
//putchar('T');
|
||||
}
|
||||
txfile_bytes+=Tx_length;
|
||||
|
||||
if ((files_used & TX_FILE_USED) && tx_fd){
|
||||
rlen=fread(pTx_data,
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
|
||||
if (!rlen){
|
||||
printf("\nTx of file %s is done %i bytes!\n",
|
||||
tx_file,txfile_bytes);
|
||||
write_enable=0;
|
||||
}
|
||||
if (Tx_length != rlen){
|
||||
Tx_length = rlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_delay){
|
||||
sleep(tx_delay);
|
||||
}
|
||||
|
||||
if (tx_size && Tx_count == tx_cnt && !(files_used & TX_FILE_USED)){
|
||||
write_enable=0;
|
||||
if (!rx_cnt){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
handle_socket_exit:
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
close (sock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call handle_socket() 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);
|
||||
|
||||
proceed = MakeConnection();
|
||||
if( proceed == WAN_TRUE){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
void sig_end(int sigid)
|
||||
{
|
||||
|
||||
printf("Got Signal %i\n",sigid);
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
if (sock){
|
||||
close (sock);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void check_for_zeros(unsigned char *data, int len, int cnt, int bytes)
|
||||
{
|
||||
int i;
|
||||
int zero_cnt=0;
|
||||
|
||||
for (i=0;i<len;i++){
|
||||
if (data[i]==0){
|
||||
if (++zero_cnt>1){
|
||||
printf("\nSENDING MULTIPLE ZEROS: Cnt %i, Len %i Bytes %i\n",
|
||||
cnt,len,bytes);
|
||||
}
|
||||
}else{
|
||||
zero_cnt=0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
VPATH = $(SYSINC)
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I ../lib -I../../lib -I$(SYSINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: ss7_monitor_api
|
||||
@echo "Ok."
|
||||
|
||||
ss7_monitor_api: ss7_monitor_api.c ../../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
bitstrm_api: bitstrm_api.c ../../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
clean:
|
||||
rm -f ss7_monitor_api
|
|
@ -0,0 +1,363 @@
|
|||
/*****************************************************************************
|
||||
* ss7_monitor_api.c
|
||||
*
|
||||
* SS7 Monitor API: Sample Module
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 2000-2003 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#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];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection(void);
|
||||
void handle_socket( void);
|
||||
void sig_end(int sigid);
|
||||
|
||||
int sock;
|
||||
FILE *tx_fd=NULL,*rx_fd=NULL;
|
||||
|
||||
#if 0
|
||||
void check_for_zeros(unsigned char *data, int len, int cnt, int bytes);
|
||||
#endif
|
||||
|
||||
/***************************************************
|
||||
* 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( WAN_FALSE );
|
||||
} /* if */
|
||||
|
||||
printf("\nConnecting to router %s, interface %s prot %x active ch %x\n",
|
||||
card_name,
|
||||
if_name,htons(SS7_MONITOR_PROT),
|
||||
tx_cnt);
|
||||
|
||||
strcpy(sa.sll_device, if_name);
|
||||
strcpy(sa.sll_card, card_name);
|
||||
sa.sll_prot = ds_prot;
|
||||
sa.sll_prot_opt = ds_prot_opt;
|
||||
sa.sll_mult_cnt = ds_max_mult_cnt;
|
||||
sa.sll_active_ch = ds_active_ch;
|
||||
|
||||
/* sa.sll_seven_bit_hdlc
|
||||
* 0: Use 8 bit hdlc engine
|
||||
* 1: Use 7 bit hdlc engine */
|
||||
sa.sll_seven_bit_hdlc = ds_7bit_hdlc;
|
||||
sa.sll_protocol = htons(SS7_MONITOR_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(WAN_TRUE);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* 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 {
|
||||
* unsigned char SIO 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;
|
||||
* unsigned char data[1] PACKED;
|
||||
* } api_rx_element_t;
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
void handle_socket(void)
|
||||
{
|
||||
unsigned int Rx_count;
|
||||
wp_sock_rx_element_t* api_rx_el;
|
||||
fd_set ready, oob;
|
||||
int err,i;
|
||||
void *pRx_data;
|
||||
time_t time_stamp;
|
||||
struct timeval time_gtd;
|
||||
|
||||
pRx_data = (void*)&Rx_data[sizeof(wp_sock_rx_hdr_t)];
|
||||
|
||||
Rx_count = 0;
|
||||
|
||||
printf("\n\nSocket Handler: Rx=%d RxCnt=%i\n",
|
||||
read_enable,rx_cnt);
|
||||
|
||||
/* If running HDLC_STREAMING then the received CRC bytes
|
||||
* will be passed to the application as part of the
|
||||
* received data.
|
||||
*/
|
||||
|
||||
|
||||
if (files_used & RX_FILE_USED){
|
||||
rx_fd=fopen(rx_file,"w");
|
||||
if (!rx_fd){
|
||||
printf("Failed to open file %s\n",rx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
printf("Opening %s rx file\n",rx_file);
|
||||
}
|
||||
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
fflush(stdout);
|
||||
if (select(sock + 1,&ready, NULL, &oob, NULL)){
|
||||
|
||||
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 CMD Exiting\n");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&ready)){
|
||||
try_rx_again:
|
||||
err = recv(sock, Rx_data, MAX_RX_DATA, 0);
|
||||
|
||||
if (!read_enable){
|
||||
goto bitstrm_skip_read;
|
||||
}
|
||||
|
||||
/* err indicates bytes received */
|
||||
if (err > 0){
|
||||
|
||||
api_rx_el = (wp_sock_rx_element_t*)&Rx_data[0];
|
||||
|
||||
/* Check the packet length */
|
||||
Rx_lgth = err - sizeof(wp_sock_rx_hdr_t);
|
||||
if(Rx_lgth<=0) {
|
||||
printf("\nShort frame received (%d)\n",
|
||||
Rx_lgth);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (direction != -1 &&
|
||||
direction != api_rx_el->api_rx_hdr.direction){
|
||||
goto bitstrm_skip_read;
|
||||
}
|
||||
|
||||
gettimeofday(&time_gtd,NULL);
|
||||
time(&time_stamp);
|
||||
|
||||
if ((files_used & RX_FILE_USED) && rx_fd){
|
||||
fprintf(rx_fd,"%s: Len=%i : AbsTime(sec:usec): %lu:%lu : Time Stamp: %s",
|
||||
api_rx_el->api_rx_hdr.direction?"TX":"RX",
|
||||
Rx_lgth,
|
||||
time_gtd.tv_sec,
|
||||
time_gtd.tv_usec,
|
||||
ctime(&time_stamp));
|
||||
for(i=0; i<Rx_lgth; i++) {
|
||||
fprintf(rx_fd,"%02X ", api_rx_el->data[i]);
|
||||
}
|
||||
fprintf(rx_fd,"\n\n");
|
||||
}
|
||||
|
||||
++Rx_count;
|
||||
|
||||
if (verbose){
|
||||
printf("%s: Len=%i Count=%i Time Stamp: %s",
|
||||
api_rx_el->api_rx_hdr.direction?"TX":"RX",
|
||||
Rx_lgth,Rx_count,
|
||||
ctime(&time_stamp));
|
||||
|
||||
for(i=0;i<Rx_lgth; i ++) {
|
||||
printf("%02X ", api_rx_el->data[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
|
||||
}else{
|
||||
if (!(Rx_count % 10)){
|
||||
if (api_rx_el->api_rx_hdr.direction){
|
||||
putchar('T');
|
||||
}else{
|
||||
putchar('R');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rx_cnt == Rx_count){
|
||||
printf("Rxcnt %i == RxCount=%i\n",rx_cnt,Rx_count);
|
||||
break;
|
||||
}
|
||||
|
||||
goto try_rx_again;
|
||||
}
|
||||
bitstrm_skip_read:
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
close (sock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call handle_socket() to read the socket
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
|
||||
read_enable=1;
|
||||
|
||||
proceed=init_args(argc,argv);
|
||||
if (proceed != WAN_TRUE){
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
signal(SIGINT,&sig_end);
|
||||
|
||||
proceed = MakeConnection();
|
||||
if( proceed == WAN_TRUE){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
void sig_end(int sigid)
|
||||
{
|
||||
|
||||
printf("Got Signal %i\n",sigid);
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
if (sock){
|
||||
close (sock);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void check_for_zeros(unsigned char *data, int len, int cnt, int bytes)
|
||||
{
|
||||
int i;
|
||||
int zero_cnt=0;
|
||||
|
||||
for (i=0;i<len;i++){
|
||||
if (data[i]==0){
|
||||
if (++zero_cnt>1){
|
||||
printf("\nSENDING MULTIPLE ZEROS: Cnt %i, Len %i Bytes %i\n",
|
||||
cnt,len,bytes);
|
||||
}
|
||||
}else{
|
||||
zero_cnt=0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: bstrm_file_client \
|
||||
bstrm_file_server \
|
||||
bstrm_gen_file
|
||||
@echo "Ok."
|
||||
|
||||
bstrm_file_client: bstrm_file_client.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
|
||||
bstrm_file_server: bstrm_file_server.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
bstrm_gen_file: bstrm_gen_file.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f bstrm_file_server
|
||||
rm -f bstrm_file_client
|
||||
rm -f bstrm_gen_file
|
|
@ -0,0 +1,413 @@
|
|||
/*****************************************************************************
|
||||
* chdlc_api.c CHDLC API: Receive Module
|
||||
*
|
||||
* Author(s): Gideon Hack & Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <wait.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_chdlc.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define MAX_NUM_OF_TIMESLOTS 31
|
||||
|
||||
#define LGTH_CRC_BYTES 2
|
||||
#define MAX_TX_DATA MAX_NUM_OF_TIMESLOTS*10 /* Size of tx data */
|
||||
#define MAX_FRAMES 10000 /* Number of frames to transmit */
|
||||
|
||||
#define WRITE 1
|
||||
#define MAX_IF_NAME 20
|
||||
|
||||
#define ALL_OK 0
|
||||
#define BOARD_UNDERRUN 1
|
||||
#define TX_ISR_UNDERRUN 2
|
||||
#define UNKNOWN_ERROR 4
|
||||
#define RX_FILE_NAME "rx_file.txt"
|
||||
|
||||
#undef RX_FILE_GEN
|
||||
#define TX_FILE_SEND
|
||||
#define TX_FILE_NAME "tx_ch_file.b"
|
||||
#define FILE_DIR "test_file"
|
||||
|
||||
#define HEADER_SZ sizeof(api_tx_hdr_t)
|
||||
typedef struct {
|
||||
int sock;
|
||||
int rx_cnt;
|
||||
int tx_cnt;
|
||||
int data;
|
||||
char if_name[MAX_IF_NAME+1];
|
||||
|
||||
FILE *rx_file;
|
||||
char rx_file_name[MAX_IF_NAME+20+1];
|
||||
int rx_bytes;
|
||||
|
||||
FILE *tx_file;
|
||||
char tx_file_name[MAX_IF_NAME+20+1];
|
||||
int tx_bytes;
|
||||
} timeslot_t;
|
||||
|
||||
|
||||
timeslot_t tslot_array[MAX_NUM_OF_TIMESLOTS];
|
||||
|
||||
|
||||
|
||||
/*===================================================
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*==================================================*/
|
||||
|
||||
int MakeConnection(timeslot_t *slot, char *router_name )
|
||||
{
|
||||
struct wan_sockaddr_ll sa;
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
errno = 0;
|
||||
slot->sock = socket(AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( slot->sock < 0 ) {
|
||||
perror("Socket");
|
||||
return( FALSE );
|
||||
} /* if */
|
||||
|
||||
printf("\nConnecting to router %s, interface %s\n", router_name, slot->if_name);
|
||||
|
||||
strcpy( sa.sll_device, slot->if_name);
|
||||
strcpy( sa.sll_card, router_name);
|
||||
sa.sll_protocol = htons(PVC_PROT);
|
||||
sa.sll_family=AF_WANPIPE;
|
||||
|
||||
if(bind(slot->sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){
|
||||
perror("bind");
|
||||
printf("Failed to bind a socket to %s interface\n",slot->if_name);
|
||||
exit(0);
|
||||
}
|
||||
printf("Socket bound to %s\n\n",slot->if_name);
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void process_con_rx(timeslot_t *slot)
|
||||
{
|
||||
unsigned int Rx_count;
|
||||
fd_set ready;
|
||||
int err,serr,i;
|
||||
int stream_sync=0;
|
||||
unsigned char Rx_data[1600];
|
||||
int error_bit=0;
|
||||
int ok=0,brd=0,txisr=0,unknown=0;
|
||||
struct timeval tv;
|
||||
int ferr;
|
||||
int frame_count=-1;
|
||||
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
|
||||
Rx_count = 0;
|
||||
|
||||
slot->rx_file=NULL;
|
||||
|
||||
printf("%s: Rx Slot %i looking for 0x%x\n",slot->if_name,slot->sock,slot->data);
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_SET(slot->sock,&ready);
|
||||
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active sockets.
|
||||
*/
|
||||
|
||||
error_bit=0;
|
||||
if((serr=select(slot->sock + 1,&ready, NULL, NULL, &tv))){
|
||||
|
||||
/* Check for rx packets */
|
||||
if (FD_ISSET(slot->sock,&ready)){
|
||||
err = recv(slot->sock, Rx_data, sizeof(Rx_data), 0);
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\n%s: Error selecting rx socket rc=0x%x errno=0x%x\n",
|
||||
slot->if_name,serr,errno);
|
||||
perror("Select: ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void process_con_tx(timeslot_t *slot)
|
||||
{
|
||||
unsigned int Tx_count,Tx_length;
|
||||
fd_set read,write;
|
||||
int err;
|
||||
unsigned char Tx_data[MAX_TX_DATA + sizeof(api_tx_hdr_t)];
|
||||
int rlen;
|
||||
int i=0;
|
||||
unsigned char Rx_data[1600];
|
||||
|
||||
i=0;
|
||||
|
||||
Tx_count = 0;
|
||||
Tx_length = MAX_TX_DATA;
|
||||
|
||||
/* If running HDLC_STREAMING then the received CRC bytes
|
||||
* will be passed to the application as part of the
|
||||
* received data. The CRC bytes will be appended as the
|
||||
* last two bytes in the rx packet.
|
||||
*/
|
||||
|
||||
memset(&Tx_data[0],0,MAX_TX_DATA + HEADER_SZ);
|
||||
|
||||
#ifdef TX_FILE_SEND
|
||||
sprintf(slot->tx_file_name, "%s/%s",FILE_DIR,TX_FILE_NAME);
|
||||
|
||||
slot->tx_file = fopen(slot->tx_file_name,"rb");
|
||||
if (!slot->tx_file){
|
||||
printf("%s: Failed to open TX File: %s\n",
|
||||
slot->if_name,
|
||||
slot->tx_file_name);
|
||||
return;
|
||||
}
|
||||
|
||||
rlen=fread((void*)&Tx_data[HEADER_SZ],sizeof(char),Tx_length,slot->tx_file);
|
||||
if (!rlen){
|
||||
printf("%s: File failed to read %s\n",
|
||||
slot->if_name,
|
||||
slot->tx_file_name);
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
Tx_data[0]=0x91;
|
||||
for (i=1;i<Tx_length;i++){
|
||||
Tx_data[i] = slot->data;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
printf("%s: Tx Starting to write on sock %i\n",slot->if_name,slot->sock);
|
||||
|
||||
//pause();
|
||||
slot->tx_bytes=0;
|
||||
for(;;) {
|
||||
FD_ZERO(&write);
|
||||
FD_SET(slot->sock,&write);
|
||||
FD_SET(slot->sock,&read);
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active sockets.
|
||||
*/
|
||||
|
||||
if(select(slot->sock + 1,&read, &write, NULL, NULL)){
|
||||
|
||||
if (FD_ISSET(slot->sock,&read)){
|
||||
err = recv(slot->sock, Rx_data, sizeof(Rx_data), 0);
|
||||
}
|
||||
|
||||
/* Check if the socket is ready to tx data */
|
||||
if (FD_ISSET(slot->sock,&write)){
|
||||
|
||||
err = send(slot->sock,Tx_data, Tx_length+HEADER_SZ, 0);
|
||||
|
||||
if (err > 0){
|
||||
#ifdef TX_FILE_SEND
|
||||
err-=HEADER_SZ;
|
||||
slot->tx_bytes+=err;
|
||||
|
||||
rlen=fread((void*)&Tx_data[HEADER_SZ],
|
||||
sizeof(char),
|
||||
Tx_length,slot->tx_file);
|
||||
if (!rlen){
|
||||
printf("%s: Tx of file %s done!\n",
|
||||
slot->if_name,
|
||||
slot->tx_file_name);
|
||||
return;
|
||||
|
||||
}else if (rlen < Tx_length){
|
||||
Tx_length=rlen;
|
||||
printf("%s: Sending last part of the file\n",slot->if_name);
|
||||
}
|
||||
#else
|
||||
slot->tx_bytes+=err;
|
||||
|
||||
Tx_data[HEADER_SZ]=slot->data;
|
||||
|
||||
if (slot->tx_bytes >= ((MAX_FRAMES*MAX_TX_DATA)-240) &&
|
||||
slot->tx_bytes<(MAX_FRAMES*MAX_TX_DATA)){
|
||||
|
||||
printf("Sending out last frame!\n");
|
||||
Tx_data[HEADER_SZ+Tx_length-1]=0x71;
|
||||
|
||||
}else if (slot->tx_bytes >= (MAX_FRAMES*MAX_TX_DATA)){
|
||||
printf("Sending out last frame sent ok!\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Packet sent ok */
|
||||
//printf("\t\t%s:Packet sent: Len=%i Data=0x%x : %i\n",
|
||||
// slot->if_name,err,slot->data,++Tx_count);
|
||||
//putchar('T');
|
||||
}else{
|
||||
if (errno != EBUSY){
|
||||
printf("Errno = %i EBUSY=%i\n",errno,-EBUSY);
|
||||
perror("Send Failed: ");
|
||||
break;
|
||||
}
|
||||
|
||||
/* The driver is busy, we must requeue this
|
||||
* tx packet, and try resending it again
|
||||
* later. */
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
printf("\nError selecting socket\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sig_handle(int sigio)
|
||||
{
|
||||
printf("End\n");
|
||||
|
||||
kill(0,SIGTERM);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call process_con() to read/write the socket
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
char router_name[20];
|
||||
int err,x,i;
|
||||
|
||||
if (argc < 4 || argc%2){
|
||||
printf("Usage: rec_wan_sock <router name> <interface name> <data> ...\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
signal(SIGINT,&sig_handle);
|
||||
memset(&tslot_array,0,sizeof(tslot_array));
|
||||
|
||||
strncpy(router_name,argv[1],(sizeof(router_name)-1));
|
||||
|
||||
for (x=0,i=2;i<argc;x++,i+=2){
|
||||
|
||||
strncpy(tslot_array[x].if_name, argv[i], MAX_IF_NAME);
|
||||
tslot_array[x].data = atoi(argv[i+1]);
|
||||
|
||||
#if 1
|
||||
proceed = MakeConnection(&tslot_array[x],router_name);
|
||||
if( proceed == TRUE ){
|
||||
|
||||
printf("Creating %s with tx data 0x%x : Sock=%i : x=%i\n",
|
||||
tslot_array[x].if_name,
|
||||
tslot_array[x].data,
|
||||
tslot_array[x].sock,
|
||||
x);
|
||||
|
||||
if (!fork()){
|
||||
process_con_tx(&tslot_array[x]);
|
||||
|
||||
if (tslot_array[x].tx_file){
|
||||
fclose(tslot_array[x].tx_file);
|
||||
}
|
||||
|
||||
close(tslot_array[x].sock);
|
||||
printf("%s: Tx child exit: Bytes %i\n",
|
||||
tslot_array[x].if_name,
|
||||
tslot_array[x].tx_bytes);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (x=0;x<MAX_NUM_OF_TIMESLOTS;x++){
|
||||
if (tslot_array[x].sock){
|
||||
close(tslot_array[x].sock);
|
||||
tslot_array[x].sock=0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the clear call children */
|
||||
//pause();
|
||||
|
||||
{
|
||||
pid_t pid;
|
||||
int stat;
|
||||
while ((pid=waitpid(-1,&stat,0)) > 0){
|
||||
//printf("Child %d terminated\n",pid);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
err=system("diff --brief test_file/rx_wp1_bstrm.b test_file/tx_file.b");
|
||||
if (err == 0){
|
||||
printf("Rx file identical to Tx file: Success!\n");
|
||||
}else{
|
||||
printf("Rx file corrupted, different than Tx: ERROR!\n");
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
};
|
|
@ -0,0 +1,581 @@
|
|||
/*****************************************************************************
|
||||
* chdlc_api.c CHDLC API: Receive Module
|
||||
*
|
||||
* Author(s): Gideon Hack & Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <wait.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_chdlc.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define MAX_NUM_OF_TIMESLOTS 31
|
||||
|
||||
#define LGTH_CRC_BYTES 2
|
||||
#define MAX_TX_DATA MAX_NUM_OF_TIMESLOTS*10 /* Size of tx data */
|
||||
#define MAX_FRAMES 10000 /* Number of frames to transmit */
|
||||
|
||||
#define WRITE 1
|
||||
#define MAX_IF_NAME 20
|
||||
|
||||
#define ALL_OK 0
|
||||
#define BOARD_UNDERRUN 1
|
||||
#define TX_ISR_UNDERRUN 2
|
||||
#define UNKNOWN_ERROR 4
|
||||
#define RX_FILE_NAME "rx_file.txt"
|
||||
|
||||
#define RX_FILE_GEN
|
||||
#define TX_FILE_SEND
|
||||
#define TX_FILE_NAME "tx_ch_file.b"
|
||||
#define FILE_DIR "test_file"
|
||||
|
||||
#define CH_1_DATA 0x20
|
||||
#define DIFF_BETWEEN_CH 3
|
||||
|
||||
#define HEADER_SZ sizeof(api_tx_hdr_t)
|
||||
|
||||
typedef struct {
|
||||
int sock;
|
||||
int rx_cnt;
|
||||
int tx_cnt;
|
||||
int data;
|
||||
char if_name[MAX_IF_NAME+1];
|
||||
|
||||
FILE *rx_file;
|
||||
char rx_file_name[MAX_IF_NAME+20+1];
|
||||
int rx_bytes;
|
||||
|
||||
FILE *tx_file;
|
||||
char tx_file_name[MAX_IF_NAME+20+1];
|
||||
int tx_bytes;
|
||||
|
||||
unsigned char rx_prev_data[MAX_NUM_OF_TIMESLOTS];
|
||||
} timeslot_t;
|
||||
|
||||
|
||||
timeslot_t tslot_array[MAX_NUM_OF_TIMESLOTS];
|
||||
unsigned char rx_test_data[MAX_NUM_OF_TIMESLOTS];
|
||||
|
||||
|
||||
/*===================================================
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*==================================================*/
|
||||
|
||||
int MakeConnection(timeslot_t *slot, char *router_name )
|
||||
{
|
||||
struct wan_sockaddr_ll sa;
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
errno = 0;
|
||||
slot->sock = socket(AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( slot->sock < 0 ) {
|
||||
perror("Socket");
|
||||
return( FALSE );
|
||||
} /* if */
|
||||
|
||||
printf("\nConnecting to router %s, interface %s\n", router_name, slot->if_name);
|
||||
|
||||
strcpy( sa.sll_device, slot->if_name);
|
||||
strcpy( sa.sll_card, router_name);
|
||||
sa.sll_protocol = htons(PVC_PROT);
|
||||
sa.sll_family=AF_WANPIPE;
|
||||
|
||||
if(bind(slot->sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){
|
||||
perror("bind");
|
||||
printf("Failed to bind a socket to %s interface\n",slot->if_name);
|
||||
exit(0);
|
||||
}
|
||||
printf("Socket bound to %s\n\n",slot->if_name);
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void process_con_rx(timeslot_t *slot)
|
||||
{
|
||||
unsigned int Rx_count;
|
||||
fd_set ready;
|
||||
int err,serr,i;
|
||||
int stream_sync=0;
|
||||
unsigned char Rx_data_buf[1600+HEADER_SZ];
|
||||
unsigned char *Rx_data;
|
||||
int error_bit=0;
|
||||
int ok=0,brd=0,txisr=0,unknown=0;
|
||||
struct timeval tv;
|
||||
int ferr;
|
||||
int frame_count=-1;
|
||||
int channel=0;
|
||||
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
|
||||
Rx_count = 0;
|
||||
|
||||
slot->rx_file=NULL;
|
||||
|
||||
#ifdef RX_FILE_GEN
|
||||
sprintf(slot->rx_file_name, "%s/rx_%s.b",FILE_DIR,slot->if_name);
|
||||
unlink(slot->rx_file_name);
|
||||
slot->rx_file = fopen(slot->rx_file_name,"wb");
|
||||
if (!slot->rx_file){
|
||||
printf("%s: Failed to open RX File: %s\n",
|
||||
slot->if_name,
|
||||
slot->rx_file_name);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%s: Rx Slot %i looking for 0x%x RxSize=%i\n",
|
||||
slot->if_name,slot->sock,slot->data,sizeof(Rx_data));
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_SET(slot->sock,&ready);
|
||||
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active sockets.
|
||||
*/
|
||||
|
||||
error_bit=0;
|
||||
if((serr=select(slot->sock + 1,&ready, NULL, NULL, &tv))){
|
||||
|
||||
/* Check for rx packets */
|
||||
if (FD_ISSET(slot->sock,&ready)){
|
||||
|
||||
err = recv(slot->sock, Rx_data_buf, sizeof(Rx_data_buf), 0);
|
||||
|
||||
/* err indicates bytes received */
|
||||
if(err > HEADER_SZ) {
|
||||
|
||||
err-=HEADER_SZ;
|
||||
Rx_data=&Rx_data_buf[HEADER_SZ];
|
||||
|
||||
/* Rx packet recevied OK
|
||||
* Each rx packet will contain 16 bytes of
|
||||
* rx header, that must be removed. The
|
||||
* first byte of the 16 byte header will
|
||||
* indicate an error condition.
|
||||
*/
|
||||
|
||||
|
||||
for (i=0;i<err;i++){
|
||||
//if (Rx_data[i] >= 0x20 && Rx_data[i] <= 0x67){
|
||||
if (Rx_data[i] >= 0x20){
|
||||
if (!stream_sync){
|
||||
printf("%s: Rx: Sync Started Data=0x%x\n",
|
||||
slot->if_name,Rx_data[i]);
|
||||
stream_sync=1;
|
||||
error_bit=0;
|
||||
frame_count=1;
|
||||
ok=0;
|
||||
slot->rx_bytes=0;
|
||||
channel=0;
|
||||
|
||||
#ifdef RX_FILE_GEN
|
||||
ferr=fwrite((void *)&Rx_data[i],
|
||||
sizeof(char), (err-i), slot->rx_file);
|
||||
if (ferr != (err-i)){
|
||||
printf("%s: Failed to write 1st in Rx file %s len=%i\n",
|
||||
slot->if_name,slot->rx_file_name,
|
||||
(err-i));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (stream_sync){
|
||||
if (Rx_data[i] != rx_test_data[channel]){
|
||||
|
||||
if ((Rx_data[i] > rx_test_data[channel]) &&
|
||||
(Rx_data[i] <= rx_test_data[channel]+2)){
|
||||
//OK
|
||||
}else{
|
||||
printf("Error: Ch %i, RxData=%x\n",
|
||||
channel+1, Rx_data[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
channel=(++channel%MAX_NUM_OF_TIMESLOTS);
|
||||
}
|
||||
|
||||
ok++;
|
||||
slot->rx_bytes++;
|
||||
|
||||
}else if (Rx_data[i] == 0x02){
|
||||
error_bit |= BOARD_UNDERRUN;
|
||||
brd++;
|
||||
}else if (Rx_data[i] == 0x04){
|
||||
txisr++;
|
||||
error_bit |= TX_ISR_UNDERRUN;
|
||||
}else{
|
||||
unknown++;
|
||||
error_bit |= UNKNOWN_ERROR;
|
||||
}
|
||||
#ifdef RX_FILE_GEN
|
||||
if (stream_sync && error_bit){
|
||||
|
||||
if (frame_count==1){
|
||||
printf("\n%s: Rx: Out of Sync Received on first frame 0x%x!\n",
|
||||
slot->if_name,Rx_data[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\n%s: Rx: Out of Sync Received :%s Offset=%i 0x%x!\n\n",
|
||||
slot->if_name,
|
||||
((error_bit&TX_ISR_UNDERRUN) ? "TX UNDR" :
|
||||
(error_bit&BOARD_UNDERRUN) ? "BRD UNDR" :
|
||||
"UNK UNDR"),
|
||||
i,Rx_data[i]);
|
||||
|
||||
|
||||
if (i > 0){
|
||||
ferr=fwrite((void *)&Rx_data[0],
|
||||
sizeof(char), i, slot->rx_file);
|
||||
if (ferr != i){
|
||||
printf("%s:
|
||||
Failed to write in Rx file %s len=%i\n",
|
||||
slot->if_name,
|
||||
slot->rx_file_name,
|
||||
i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (stream_sync){
|
||||
if (++frame_count == 2){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (stream_sync && error_bit){
|
||||
printf("\n%s: Out of Sync Received :%s !\n\n",
|
||||
slot->if_name,
|
||||
((error_bit&TX_ISR_UNDERRUN) ? "TX UNDR" :
|
||||
(error_bit&BOARD_UNDERRUN) ? "BRD UNDR" :
|
||||
"UNK UNDR"));
|
||||
return;
|
||||
}
|
||||
#ifdef RX_FILE_GEN
|
||||
if (stream_sync && !error_bit){
|
||||
ferr=fwrite((void *)&Rx_data[0],
|
||||
sizeof(char), (err), slot->rx_file);
|
||||
if (ferr != err){
|
||||
printf("%s: Failed to write 1st in Rx file %s len=%i\n",
|
||||
slot->if_name,slot->rx_file_name,
|
||||
err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//putchar('\r');
|
||||
//printf("ok=%i brd=%i tx=%i unk=%i len=%i data=%i",
|
||||
// ok,brd,txisr,unknown,err,slot->data);
|
||||
|
||||
//fflush(stdout);
|
||||
|
||||
} else {
|
||||
printf("\n%s: Error receiving data\n",slot->if_name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\n%s: Error selecting rx socket rc=0x%x errno=0x%x\n",
|
||||
slot->if_name,serr,errno);
|
||||
perror("Select: ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void process_con_tx(timeslot_t *slot)
|
||||
{
|
||||
unsigned int Tx_count,Tx_length;
|
||||
fd_set write;
|
||||
int err;
|
||||
unsigned char Tx_data[MAX_TX_DATA + sizeof(api_tx_hdr_t)];
|
||||
int rlen;
|
||||
int i=0;
|
||||
|
||||
i=0;
|
||||
|
||||
Tx_count = 0;
|
||||
Tx_length = MAX_TX_DATA;
|
||||
|
||||
/* If running HDLC_STREAMING then the received CRC bytes
|
||||
* will be passed to the application as part of the
|
||||
* received data. The CRC bytes will be appended as the
|
||||
* last two bytes in the rx packet.
|
||||
*/
|
||||
|
||||
memset(&Tx_data[0],0,MAX_TX_DATA + sizeof(api_tx_hdr_t));
|
||||
|
||||
#ifdef TX_FILE_SEND
|
||||
// sprintf(slot->tx_file_name, "tx_%s.b",slot->if_name);
|
||||
sprintf(slot->tx_file_name, "%s/%s",FILE_DIR,TX_FILE_NAME);
|
||||
|
||||
slot->tx_file = fopen(slot->tx_file_name,"rb");
|
||||
if (!slot->tx_file){
|
||||
printf("%s: Failed to open TX File: %s\n",
|
||||
slot->if_name,
|
||||
slot->tx_file_name);
|
||||
return;
|
||||
}
|
||||
|
||||
rlen=fread((void*)&Tx_data[0],sizeof(char),Tx_length,slot->tx_file);
|
||||
if (!rlen){
|
||||
printf("%s: File failed to read %s\n",
|
||||
slot->if_name,
|
||||
slot->tx_file_name);
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
Tx_data[0]=0x91;
|
||||
for (i=1;i<Tx_length;i++){
|
||||
Tx_data[i] = slot->data;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
printf("%s: Tx Starting to write on sock %i\n",slot->if_name,slot->sock);
|
||||
|
||||
//pause();
|
||||
slot->tx_bytes=0;
|
||||
for(;;) {
|
||||
FD_ZERO(&write);
|
||||
FD_SET(slot->sock,&write);
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active sockets.
|
||||
*/
|
||||
|
||||
if(select(slot->sock + 1,NULL, &write, NULL, NULL)){
|
||||
|
||||
/* Check if the socket is ready to tx data */
|
||||
if (FD_ISSET(slot->sock,&write)){
|
||||
|
||||
err = send(slot->sock,Tx_data, Tx_length, 0);
|
||||
|
||||
if (err > 0){
|
||||
#ifdef TX_FILE_SEND
|
||||
slot->tx_bytes+=err;
|
||||
|
||||
rlen=fread((void*)&Tx_data[0],
|
||||
sizeof(char),
|
||||
Tx_length,slot->tx_file);
|
||||
if (!rlen){
|
||||
printf("%s: Tx of file %s done!\n",
|
||||
slot->if_name,
|
||||
slot->tx_file_name);
|
||||
return;
|
||||
|
||||
}else if (rlen < Tx_length){
|
||||
Tx_length=rlen;
|
||||
printf("%s: Sending last part of the file\n",slot->if_name);
|
||||
}
|
||||
#else
|
||||
slot->tx_bytes+=err;
|
||||
|
||||
Tx_data[0]=slot->data;
|
||||
|
||||
if (slot->tx_bytes >= ((MAX_FRAMES*MAX_TX_DATA)-240) &&
|
||||
slot->tx_bytes<(MAX_FRAMES*MAX_TX_DATA)){
|
||||
|
||||
printf("Sending out last frame!\n");
|
||||
Tx_data[Tx_length-1]=0x71;
|
||||
|
||||
}else if (slot->tx_bytes >= (MAX_FRAMES*MAX_TX_DATA)){
|
||||
printf("Sending out last frame sent ok!\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Packet sent ok */
|
||||
//printf("\t\t%s:Packet sent: Len=%i Data=0x%x : %i\n",
|
||||
// slot->if_name,err,slot->data,++Tx_count);
|
||||
//putchar('T');
|
||||
}else{
|
||||
if (errno != EBUSY){
|
||||
printf("Errno = %i EBUSY=%i\n",errno,-EBUSY);
|
||||
perror("Send Failed: ");
|
||||
break;
|
||||
}
|
||||
|
||||
/* The driver is busy, we must requeue this
|
||||
* tx packet, and try resending it again
|
||||
* later. */
|
||||
}
|
||||
|
||||
}else{
|
||||
printf("Error Tx nothing IFFSET\n");
|
||||
}
|
||||
} else {
|
||||
printf("\nError selecting socket\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sig_handle(int sigio)
|
||||
{
|
||||
printf("End\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call process_con() to read/write the socket
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
char router_name[20];
|
||||
char global_if_name[20];
|
||||
int err,x,i;
|
||||
|
||||
if (argc < 4 || argc%2){
|
||||
printf("Usage: rec_wan_sock <router name> <interface name> <data> ...\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
signal(SIGINT,&sig_handle);
|
||||
memset(&tslot_array,0,sizeof(tslot_array));
|
||||
|
||||
strncpy(router_name,argv[1],(sizeof(router_name)-1));
|
||||
|
||||
for (x=0;x<MAX_NUM_OF_TIMESLOTS;x++){
|
||||
rx_test_data[x]=CH_1_DATA+(x*DIFF_BETWEEN_CH);
|
||||
}
|
||||
|
||||
for (x=0,i=2;i<argc;x++,i+=2){
|
||||
|
||||
strncpy(tslot_array[x].if_name, argv[i], MAX_IF_NAME);
|
||||
strncpy(global_if_name,argv[i], MAX_IF_NAME);
|
||||
tslot_array[x].data = atoi(argv[i+1]);
|
||||
|
||||
#if 1
|
||||
proceed = MakeConnection(&tslot_array[x],router_name);
|
||||
if( proceed == TRUE ){
|
||||
|
||||
printf("Creating %s with tx data 0x%x : Sock=%i : x=%i\n",
|
||||
tslot_array[x].if_name,
|
||||
tslot_array[x].data,
|
||||
tslot_array[x].sock,
|
||||
x);
|
||||
|
||||
if (!fork()){
|
||||
process_con_rx(&tslot_array[x]);
|
||||
|
||||
if (tslot_array[x].rx_file){
|
||||
fclose(tslot_array[x].rx_file);
|
||||
}
|
||||
|
||||
close(tslot_array[x].sock);
|
||||
printf("%s: Rx child exit: Bytes %i\n",
|
||||
tslot_array[x].if_name,
|
||||
tslot_array[x].rx_bytes);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (x=0;x<MAX_NUM_OF_TIMESLOTS;x++){
|
||||
if (tslot_array[x].sock){
|
||||
close(tslot_array[x].sock);
|
||||
tslot_array[x].sock=0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the clear call children */
|
||||
//pause();
|
||||
|
||||
{
|
||||
pid_t pid;
|
||||
int stat;
|
||||
while ((pid=waitpid(-1,&stat,0)) > 0){
|
||||
//printf("Child %d terminated\n",pid);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* Note: Change the rx file name based on the interface name you are using*/
|
||||
|
||||
unsigned char cmd_exec[100];
|
||||
sprintf(cmd_exec,"diff --brief test_file/rx_%s.b test_file/%s",
|
||||
global_if_name,TX_FILE_NAME);
|
||||
printf("Executing: %s\n",cmd_exec);
|
||||
err=system(cmd_exec);
|
||||
if (err == 0){
|
||||
printf("Rx file identical to Tx file: Success!\n");
|
||||
}else{
|
||||
printf("Rx file corrupted, different than Tx: ERROR!\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <wait.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_chdlc.h>
|
||||
|
||||
#define TX_FILE_NAME "tx_ch_file.b"
|
||||
#define FILE_DIR "test_file"
|
||||
#define MAX_CH_NUM 31
|
||||
|
||||
#define CH_1_DATA 0x20
|
||||
#define DIFF_BETWEEN_CH 3
|
||||
|
||||
#define NUM_OF_PCK_GENERATED 10000 //Equals 2.4 MB each packet is 24 bytes
|
||||
|
||||
unsigned char ch_data[MAX_CH_NUM];
|
||||
|
||||
#if 1
|
||||
unsigned char ch_scratch_data[MAX_CH_NUM];
|
||||
#else
|
||||
//unsigned char ch_scratch_data[]={0x7E,0x7E,0x7E,0x01,0xF1,0xC1,0x00,0xFC,0x7E,0x7E,0xFF,0xFF,0x7F,0x7F};
|
||||
unsigned char ch_scratch_data[]={0x7E,0x7E,0x7E,0x01,0xFF,0xC1,0xFD,0xFC,0x7E,0x7E,0x01,0x7F,0xFF,0x7F,0x7F};
|
||||
#endif
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE *file;
|
||||
unsigned char tx_file_name[100];
|
||||
int i,x;
|
||||
int ferr;
|
||||
|
||||
sprintf(tx_file_name, "%s/%s",FILE_DIR,TX_FILE_NAME);
|
||||
|
||||
file = fopen(tx_file_name,"wb");
|
||||
if (!file){
|
||||
printf("Failed to open TX File: %s\n",
|
||||
tx_file_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 1
|
||||
for (i=0;i<MAX_CH_NUM;i++){
|
||||
ch_data[i]=CH_1_DATA+(i*DIFF_BETWEEN_CH);
|
||||
//ch_data[i]=0x10;
|
||||
printf("Data CH=%i = 0x%x\n",
|
||||
(i+1),ch_data[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
for (i=0;i<NUM_OF_PCK_GENERATED;i++){
|
||||
#if 1
|
||||
for (x=0;x<MAX_CH_NUM;x++){
|
||||
ch_scratch_data[x] = ch_data[x]+(i%3);
|
||||
//ch_scratch_data[x] = 0x10;
|
||||
}
|
||||
#endif
|
||||
ferr=fwrite((void *)&ch_scratch_data[0],
|
||||
sizeof(char), sizeof(ch_scratch_data), file);
|
||||
|
||||
if (ferr != sizeof(ch_scratch_data)){
|
||||
printf("Failed to write to %s file: Invalid write len=%i instead of %i\n",
|
||||
tx_file_name,ferr,sizeof(ch_scratch_data));
|
||||
fclose(file);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
APIINC = /usr/src/linux/include
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: chdlc_api \
|
||||
chdlc_rts_cts \
|
||||
chdlc_integrity \
|
||||
chdlc_echo
|
||||
@echo "Ok."
|
||||
|
||||
chdlc_api: chdlc_api.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
chdlc_echo: chdlc_echo.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
|
||||
chdlc_rts_cts: chdlc_rts_cts.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
chdlc_integrity: chdlc_integrity.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f chdlc_api
|
||||
rm -f chdlc_rts_cts
|
||||
rm -f chdlc_integrity
|
|
@ -0,0 +1,22 @@
|
|||
CHDLC API Package
|
||||
=================
|
||||
|
||||
Author: Nenad Corbic
|
||||
Date: Jan 18, 2002
|
||||
|
||||
|
||||
|
||||
The chdlc package contains the sample client and server
|
||||
program that should be used in user application
|
||||
development.
|
||||
|
||||
|
||||
Contents of the API Package
|
||||
---------------------------
|
||||
|
||||
1) chdlc_api.c : Client application that sends and receives data.
|
||||
To disable sending of data, comment out a WRITE definition.
|
||||
|
||||
2) chdlc_rts_cts.c: Client application that should be used when
|
||||
driver has been configured for switched RTS CTS or
|
||||
idle mark.
|
|
@ -0,0 +1,465 @@
|
|||
/*****************************************************************************
|
||||
* chdlc_api.c CHDLC API: Receive Module
|
||||
*
|
||||
* Author(s): Gideon Hack & Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_chdlc.h>
|
||||
#include "lib_api.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define LGTH_CRC_BYTES 2
|
||||
#define MAX_TX_DATA 5000 /* Size of tx data */
|
||||
#define MAX_RX_DATA MAX_TX_DATA
|
||||
|
||||
|
||||
FILE *tx_fd=NULL,*rx_fd=NULL;
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Golobal data
|
||||
*==================================================*/
|
||||
|
||||
unsigned short no_CRC_bytes_Rx;
|
||||
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( sa.sll_device, if_name);
|
||||
strcpy( 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_rx_element_t* api_rx_el;
|
||||
api_tx_element_t * api_tx_el;
|
||||
fd_set ready,write,oob;
|
||||
int err,i;
|
||||
int rlen;
|
||||
int ferr;
|
||||
int txfile_bytes=0;
|
||||
void *pRx_data,*pTx_data;
|
||||
int no_CRC_bytes_Rx = LGTH_CRC_BYTES;
|
||||
|
||||
|
||||
pRx_data = (void*)&Rx_data[sizeof(api_rx_hdr_t)];
|
||||
pTx_data = (void*)&Tx_data[sizeof(api_tx_hdr_t)];
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
memset(&Tx_data[0],0,MAX_TX_DATA);
|
||||
|
||||
if (files_used & RX_FILE_USED){
|
||||
rx_fd=fopen(rx_file,"wb");
|
||||
if (!rx_fd){
|
||||
printf("Failed to open file %s\n",rx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
printf("Opening %s rx file\n",rx_file);
|
||||
}
|
||||
|
||||
|
||||
if (files_used & TX_FILE_USED){
|
||||
|
||||
tx_fd=fopen(tx_file,"rb");
|
||||
if (!tx_fd){
|
||||
printf("Failed to open file %s\n",tx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Opening %s tx file\n",tx_file);
|
||||
|
||||
rlen=fread(pTx_data,
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
|
||||
|
||||
if (!rlen){
|
||||
printf("%s: File empty!\n",
|
||||
tx_file);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
api_tx_el = (api_tx_element_t*)&Tx_data[0];
|
||||
|
||||
for (i=0;i<Tx_length;i++){
|
||||
if (tx_data == -1){
|
||||
api_tx_el->data[i] = (unsigned char)i;
|
||||
}else{
|
||||
api_tx_el->data[i] = (unsigned char)tx_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock,&write);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
if(select(sock + 1,&ready, &write, &oob, NULL)){
|
||||
|
||||
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);
|
||||
|
||||
if (!read_enable){
|
||||
goto bitstrm_skip_read;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (api_rx_el->api_rx_hdr.error_flag){
|
||||
|
||||
case 0:
|
||||
/* Rx packet is good */
|
||||
break;
|
||||
|
||||
case RX_FRM_ABORT:
|
||||
/* Frame was aborted */
|
||||
break;
|
||||
case RX_FRM_CRC_ERROR:
|
||||
/* Frame has crc error */
|
||||
break;
|
||||
case RX_FRM_OVERRUN_ERROR:
|
||||
/* Frame has an overrun error */
|
||||
break;
|
||||
default:
|
||||
/* Error with the rx packet
|
||||
* handle it ... */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((files_used & RX_FILE_USED) && rx_fd){
|
||||
ferr=fwrite(pRx_data,
|
||||
sizeof(char),
|
||||
Rx_lgth,
|
||||
rx_fd);
|
||||
if (ferr != Rx_lgth){
|
||||
printf("Error: fwrite failed: written=%i should have %i\n",
|
||||
ferr,Rx_lgth);
|
||||
}
|
||||
}
|
||||
|
||||
++Rx_count;
|
||||
|
||||
if (verbose){
|
||||
printf("Received %i Olen=%i Length = %i\n",
|
||||
Rx_count, err,Rx_lgth);
|
||||
}else{
|
||||
putchar('R');
|
||||
}
|
||||
#if 1
|
||||
if (verbose){
|
||||
printf("Data: ");
|
||||
for(i=0;(i<Rx_lgth)&&(i<32); i ++) {
|
||||
printf("0x%02X ", api_rx_el->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rx_cnt == Rx_count){
|
||||
printf("Rxcnt %i == RxCount=%i\n",rx_cnt,Rx_count);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bitstrm_skip_read:
|
||||
if (FD_ISSET(sock,&write)){
|
||||
|
||||
err = send(sock,Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0);
|
||||
|
||||
if (err <= 0){
|
||||
if (errno == EBUSY){
|
||||
if (verbose){
|
||||
printf("Sock busy try again!\n");
|
||||
}
|
||||
/* 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){
|
||||
printf("Packet sent: Sent %i : %i\n",
|
||||
err,Tx_count);
|
||||
}else{
|
||||
//putchar('T');
|
||||
}
|
||||
txfile_bytes+=Tx_length;
|
||||
|
||||
if ((files_used & TX_FILE_USED) && tx_fd){
|
||||
rlen=fread(pTx_data,
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
|
||||
if (!rlen){
|
||||
printf("\nTx of file %s is done %i bytes!\n",
|
||||
tx_file,txfile_bytes);
|
||||
break;
|
||||
}
|
||||
if (Tx_length != rlen){
|
||||
Tx_length = rlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_delay){
|
||||
sleep(tx_delay);
|
||||
}
|
||||
|
||||
if (tx_size && Tx_count == tx_cnt && !(files_used & TX_FILE_USED)){
|
||||
write_enable=0;
|
||||
if (!rx_cnt){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
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(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
proceed = MakeConnection();
|
||||
if(proceed == WAN_TRUE){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
Binary file not shown.
|
@ -0,0 +1,323 @@
|
|||
/*****************************************************************************
|
||||
* chdlc_api.c CHDLC API: Receive Module
|
||||
*
|
||||
* Author(s): Gideon Hack & Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_chdlc.h>
|
||||
#include "lib_api.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define LGTH_CRC_BYTES 2
|
||||
#define MAX_TX_DATA 5000 /* Size of tx data */
|
||||
#define MAX_RX_DATA MAX_TX_DATA
|
||||
|
||||
|
||||
static unsigned char test_data[]={0x00,0x5A, 0xAA, 0xA5, 0xFF};
|
||||
static unsigned char tx_index=0;
|
||||
|
||||
/*===================================================
|
||||
* Golobal data
|
||||
*==================================================*/
|
||||
|
||||
unsigned short no_CRC_bytes_Rx;
|
||||
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( sa.sll_device, if_name);
|
||||
strcpy( 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_rx_element_t* api_rx_el;
|
||||
fd_set ready,oob;
|
||||
int err,i;
|
||||
void *pRx_data,*pTx_data;
|
||||
int no_CRC_bytes_Rx = LGTH_CRC_BYTES;
|
||||
|
||||
|
||||
pRx_data = (void*)&Rx_data[sizeof(api_rx_hdr_t)];
|
||||
pTx_data = (void*)&Tx_data[sizeof(api_tx_hdr_t)];
|
||||
|
||||
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.
|
||||
*/
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
fflush(stdout);
|
||||
if(select(sock + 1,&ready, NULL, &oob, NULL)){
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (api_rx_el->api_rx_hdr.error_flag){
|
||||
|
||||
case 0:
|
||||
/* Rx packet is good */
|
||||
break;
|
||||
|
||||
case RX_FRM_ABORT:
|
||||
/* Frame was aborted */
|
||||
break;
|
||||
case RX_FRM_CRC_ERROR:
|
||||
/* Frame has crc error */
|
||||
break;
|
||||
case RX_FRM_OVERRUN_ERROR:
|
||||
/* Frame has an overrun error */
|
||||
break;
|
||||
default:
|
||||
/* Error with the rx packet
|
||||
* handle it ... */
|
||||
break;
|
||||
}
|
||||
|
||||
++Rx_count;
|
||||
|
||||
for (i=0;i<Rx_lgth;i++){
|
||||
if (((unsigned char*)api_rx_el->data)[i] !=
|
||||
test_data[tx_index]){
|
||||
printf("Rx Error cnt=%i: Packet corruption on offset %i\n",
|
||||
Rx_count,i);
|
||||
goto process_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (Rx_count == tx_cnt){
|
||||
Rx_count=0;
|
||||
tx_index++;
|
||||
if (tx_index >=sizeof(test_data)){
|
||||
tx_index=0;
|
||||
}
|
||||
}
|
||||
|
||||
err = send(sock,Rx_data,err-2,0);
|
||||
|
||||
if (err <= 0){
|
||||
printf("Failed to Tx Echo Data!\n");
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
process_exit:
|
||||
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(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
proceed = MakeConnection();
|
||||
if(proceed == WAN_TRUE){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
|
@ -0,0 +1,412 @@
|
|||
/*****************************************************************************
|
||||
* chdlc_api.c CHDLC API: Receive Module
|
||||
*
|
||||
* Author(s): Gideon Hack & Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_chdlc.h>
|
||||
#include "lib_api.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define LGTH_CRC_BYTES 2
|
||||
#define MAX_TX_DATA 5000 /* Size of tx data */
|
||||
#define MAX_RX_DATA MAX_TX_DATA
|
||||
|
||||
|
||||
FILE *tx_fd=NULL,*rx_fd=NULL;
|
||||
|
||||
|
||||
/*===================================================
|
||||
* 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( sa.sll_device, if_name);
|
||||
strcpy( 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<tx_size;i++){
|
||||
data[i] = test_data[tx_index];
|
||||
}
|
||||
|
||||
tx_index++;
|
||||
if (tx_index >= 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;
|
||||
|
||||
|
||||
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();
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock,&write);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
if(select(sock + 1,&ready, &write, &oob, NULL)){
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
switch (api_rx_el->api_rx_hdr.error_flag){
|
||||
|
||||
case 0:
|
||||
/* Rx packet is good */
|
||||
break;
|
||||
|
||||
case RX_FRM_ABORT:
|
||||
/* Frame was aborted */
|
||||
break;
|
||||
case RX_FRM_CRC_ERROR:
|
||||
/* Frame has crc error */
|
||||
break;
|
||||
case RX_FRM_OVERRUN_ERROR:
|
||||
/* Frame has an overrun error */
|
||||
break;
|
||||
default:
|
||||
/* Error with the rx packet
|
||||
* handle it ... */
|
||||
break;
|
||||
}
|
||||
|
||||
++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;i<Rx_lgth;i++){
|
||||
if (((unsigned char*)api_rx_el->data)[i] !=
|
||||
((unsigned char*)api_tx_el->data)[i]){
|
||||
printf("Rx Error cnt=%i: Packet corruption on offset %i\n",
|
||||
Rx_count,i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
if (verbose){
|
||||
printf("Sock busy try again!\n");
|
||||
}
|
||||
/* 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){
|
||||
printf("Packet sent: Sent %i : %i\n",
|
||||
err,Tx_count);
|
||||
}else{
|
||||
//putchar('T');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_delay){
|
||||
sleep(tx_delay);
|
||||
}
|
||||
|
||||
if (tx_size && Tx_count == tx_cnt){
|
||||
write_enable=0;
|
||||
Tx_count=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
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(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
proceed = MakeConnection();
|
||||
if(proceed == WAN_TRUE){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
|
@ -0,0 +1,367 @@
|
|||
/*****************************************************************************
|
||||
* chdlc_api.c CHDLC API: Receive Module
|
||||
*
|
||||
* Author(s): Gideon Hack & Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_chdlc.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define LGTH_CRC_BYTES 2
|
||||
#define MAX_TX_DATA 100 /* Size of tx data */
|
||||
#define MAX_FRAMES 1 /* Number of frames to transmit */
|
||||
#define TIMEOUT 1
|
||||
|
||||
#define WRITE 1
|
||||
|
||||
/*===================================================
|
||||
* Golobal data
|
||||
*==================================================*/
|
||||
|
||||
unsigned short no_CRC_bytes_Rx;
|
||||
unsigned char HDLC_streaming = FALSE;
|
||||
unsigned short Rx_lgth;
|
||||
|
||||
unsigned char Rx_data[16000];
|
||||
unsigned char Tx_data[MAX_TX_DATA + sizeof(api_tx_hdr_t)];
|
||||
int sock;
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Function Prototypes
|
||||
*==================================================*/
|
||||
int MakeConnection(char *, char *);
|
||||
void process_con( void);
|
||||
|
||||
|
||||
/*===================================================
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*==================================================*/
|
||||
|
||||
int MakeConnection(char *r_name, char *i_name )
|
||||
{
|
||||
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", r_name, i_name);
|
||||
|
||||
strcpy( sa.sll_device, i_name);
|
||||
strcpy( sa.sll_card, r_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",i_name);
|
||||
exit(0);
|
||||
}
|
||||
printf("Socket bound to %s\n\n",i_name);
|
||||
|
||||
return( TRUE );
|
||||
|
||||
}
|
||||
|
||||
/*===========================================================
|
||||
* process_con
|
||||
*
|
||||
* 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 misc_Tx_bits PACKED;
|
||||
* unsigned char reserved[14] PACKED;
|
||||
* } api_tx_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* api_tx_hdr_t api_tx_hdr PACKED;
|
||||
* void * data PACKED;
|
||||
* } api_tx_element_t;
|
||||
*
|
||||
* When device driver is configured for Switched CTS/RTS
|
||||
* or Idle Mark, the misc_Tx_bits must be used to control
|
||||
* the state of the line after the transmisstion of data is
|
||||
* complete:
|
||||
*
|
||||
* misc_Tx_bits:
|
||||
* ------------
|
||||
* 0 : No change
|
||||
*
|
||||
* DROP_RTS_AFTER_TX : Drop RTS after transmission of THIS
|
||||
* frame.
|
||||
*
|
||||
* IDLE_FLAGS_AFTER_TX : Idle flags after transmission of
|
||||
* THIS frame.
|
||||
*/
|
||||
|
||||
void process_con(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;
|
||||
int err,i;
|
||||
unsigned char *data;
|
||||
|
||||
Rx_count = 0;
|
||||
Tx_count = 0;
|
||||
Tx_length = MAX_TX_DATA;
|
||||
|
||||
/* If running HDLC_STREAMING then the received CRC bytes
|
||||
* will be passed to the application as part of the
|
||||
* received data. The CRC bytes will be appended as the
|
||||
* last two bytes in the rx packet.
|
||||
*/
|
||||
|
||||
memset(&Tx_data[0],0,MAX_TX_DATA + sizeof(api_tx_hdr_t));
|
||||
|
||||
|
||||
/* Initialize the tx packet. The 16 byte header must
|
||||
* be inserted before tx data.
|
||||
*/
|
||||
api_tx_el = (api_tx_element_t*)&Tx_data[0];
|
||||
|
||||
/* In general misc_Tx_bits are set to zero.
|
||||
* However, if device driver is configured for
|
||||
* Switched CTS/RTS or Idle Mark, the misc_Tx_bits
|
||||
* must be used as described above */
|
||||
|
||||
api_tx_el->api_tx_hdr.misc_Tx_bits = 0;
|
||||
|
||||
/* Fill in the packet data */
|
||||
|
||||
data = (unsigned char *)&api_tx_el->data;
|
||||
for (i=0;i<Tx_length;i++){
|
||||
data[i] = (unsigned char)i;
|
||||
}
|
||||
|
||||
|
||||
/* If drivers has been configured in HDLC_STREAMING
|
||||
* mode, the CRC bytes will be included into the
|
||||
* rx packet. Thus, the application should remove
|
||||
* the last two bytes of the frame.
|
||||
*
|
||||
* The no_CRC_bytes_Rx will indicate to the application
|
||||
* how many bytes to cut from the end of the rx frame.
|
||||
*
|
||||
*/
|
||||
no_CRC_bytes_Rx = 0; //LGTH_CRC_BYTES;
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_SET(sock,&ready);
|
||||
#ifdef WRITE
|
||||
FD_SET(sock,&write);
|
||||
#endif
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active sockets.
|
||||
*/
|
||||
|
||||
if(select(sock + 1,&ready, &write, NULL, NULL)){
|
||||
|
||||
|
||||
/* Check for rx packets */
|
||||
if (FD_ISSET(sock,&ready)){
|
||||
|
||||
err = recv(sock, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err indicates bytes received */
|
||||
if(err > 0) {
|
||||
|
||||
/* Rx packet recevied OK
|
||||
* Each rx packet will contain 16 bytes of
|
||||
* rx header, that must be removed. The
|
||||
* first byte of the 16 byte header will
|
||||
* indicate an error condition.
|
||||
*/
|
||||
|
||||
api_rx_el = (api_rx_element_t*)Rx_data;
|
||||
|
||||
switch (api_rx_el->api_rx_hdr.error_flag){
|
||||
|
||||
case 0:
|
||||
/* Rx packet is good */
|
||||
break;
|
||||
|
||||
case RX_FRM_ABORT:
|
||||
/* Frame was aborted */
|
||||
case RX_FRM_CRC_ERROR:
|
||||
/* Frame has crc error */
|
||||
case RX_FRM_OVERRUN_ERROR:
|
||||
/* Frame has an overrun error */
|
||||
default:
|
||||
/* Error with the rx packet
|
||||
* handle it ... */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Check the packet length, after we remove
|
||||
* the 16 bytes rx header */
|
||||
Rx_lgth = err - sizeof(api_rx_hdr_t);
|
||||
if(Rx_lgth <= no_CRC_bytes_Rx) {
|
||||
printf("\nShort frame received (%d)\n",
|
||||
Rx_lgth);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove any CRC bytes from the rx packet
|
||||
* by adjusting the rx packet length */
|
||||
Rx_lgth -= no_CRC_bytes_Rx;
|
||||
|
||||
printf("Received packet %i, length = %i\n",
|
||||
++Rx_count, Rx_lgth);
|
||||
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Check if the socket is ready to tx data */
|
||||
if (FD_ISSET(sock,&write)){
|
||||
|
||||
err = send(sock,Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0);
|
||||
|
||||
if (err > 0){
|
||||
/* Packet sent ok */
|
||||
printf("Packet sent: Sent %i : %i\n",
|
||||
err,++Tx_count);
|
||||
}else{
|
||||
/* The driver is busy, we must requeue this
|
||||
* tx packet, and try resending it again
|
||||
* later. */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Stop the program afer transmitting MAX_FRAMES */
|
||||
if (Tx_count == MAX_FRAMES)
|
||||
break;
|
||||
|
||||
} else {
|
||||
printf("\nError selecting socket\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
close (sock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call process_con() to read/write the socket
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
|
||||
if (argc != 3){
|
||||
printf("Usage: rec_wan_sock <router name> <interface name>\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
proceed = MakeConnection(argv[argc - 2], argv[argc - 1]);
|
||||
if( proceed == TRUE ){
|
||||
process_con( );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: fr_api
|
||||
@echo "Ok."
|
||||
|
||||
fr_api: fr_api.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f fr_api
|
|
@ -0,0 +1,19 @@
|
|||
FRAME RELAY API Package
|
||||
=======================
|
||||
|
||||
Author: Nenad Corbic
|
||||
Date: Mar 6, 2000
|
||||
|
||||
|
||||
|
||||
The fr package contains the sample client and server
|
||||
program that should be used in user application
|
||||
development.
|
||||
|
||||
|
||||
Contents of the API Package
|
||||
---------------------------
|
||||
|
||||
1) fr_api.c : Client application that sends and receives data.
|
||||
To disable sending of data, comment out a WRITE definition.
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
/*****************************************************************************
|
||||
* fr_api.c Frame Relay API: Transmit Module
|
||||
*
|
||||
* Author(s): Gideon Hack & Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 fr_api.c utility will bind to a socket to a frame relay 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <linux/sdla_fr.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define MIN_FRM_LGTH 100
|
||||
#define MAX_FRM_LGTH 1000
|
||||
#define NO_FRMS_TO_TX 10000
|
||||
|
||||
#define WRITE 1
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Golobal data
|
||||
*==================================================*/
|
||||
|
||||
unsigned char Tx_data[MAX_FRM_LGTH + sizeof(api_tx_hdr_t)];
|
||||
unsigned char Rx_data[MAX_FRM_LGTH + sizeof(api_tx_hdr_t)];
|
||||
|
||||
int sock;
|
||||
fd_set writeset,readset,oobset;
|
||||
struct wan_sockaddr_ll sa;
|
||||
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Function Prototypes
|
||||
*==================================================*/
|
||||
int MakeConnection(char *, char *);
|
||||
void process_con( void);
|
||||
void setup_signal_handlers (void);
|
||||
void quit (int);
|
||||
void sig_urg (int);
|
||||
|
||||
|
||||
/*====================================================
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call send_socket() to transmit data
|
||||
*
|
||||
*===================================================*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
|
||||
if (argc != 3){
|
||||
printf("Usage: fr_send <router name> <interface name>\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
proceed = MakeConnection(argv[argc - 2], argv[argc - 1]);
|
||||
|
||||
if( proceed == TRUE ){
|
||||
process_con( );
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***************************************************
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*/
|
||||
|
||||
int MakeConnection (char *r_name, char *i_name)
|
||||
{
|
||||
|
||||
errno = 0;
|
||||
sock = socket( AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( sock < 0 ) {
|
||||
perror("Socket");
|
||||
return( FALSE );
|
||||
} /* if */
|
||||
|
||||
sa.sll_family = AF_WANPIPE;
|
||||
sa.sll_protocol = htons(ETH_P_IP);
|
||||
strcpy(sa.sll_device, i_name);
|
||||
strcpy( sa.sll_card, r_name);
|
||||
sa.sll_ifindex = 0;
|
||||
|
||||
if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){
|
||||
perror("bind");
|
||||
printf("Failed to bind socket to %s interface\n",i_name);
|
||||
exit(0);
|
||||
}
|
||||
printf("Socket bound to %s\n",i_name);
|
||||
fflush(stdout);
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* process_con
|
||||
*
|
||||
* o Tx/Rx data via sockt to the frame relay network.
|
||||
* o Create a tx packet using api_tx_element_t data type.
|
||||
* o The transmit packet contains 16 bytes header
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* RX_DATA:
|
||||
* --------
|
||||
* Each rx data packet contains the 16 byte header!
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char attr 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;
|
||||
*
|
||||
* Currently the frame relay device driver doesn't use any of
|
||||
* the above fields. Thus, the user can ignore the 16 bytes
|
||||
* rx header.
|
||||
*
|
||||
* TX_DATA:
|
||||
* --------
|
||||
*
|
||||
* Each tx data packet MUST contain the 16 byte header!
|
||||
*
|
||||
* 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 frame relay device driver doesn't use any of
|
||||
* the above fields. Thus, the user can set the 16 bytes
|
||||
* tx header to ZERO.
|
||||
*/
|
||||
|
||||
void process_con(void)
|
||||
{
|
||||
unsigned int Tx_count=0,Rx_count=0;
|
||||
unsigned short Tx_length=0,Rx_length=0;
|
||||
api_tx_element_t* api_tx_el;
|
||||
api_rx_element_t* api_rx_el;
|
||||
int err=0, i=0;
|
||||
|
||||
Tx_length = MIN_FRM_LGTH;
|
||||
Rx_length = MAX_FRM_LGTH;
|
||||
|
||||
/* Initialize the tx packet. The 16 byte header must
|
||||
* be inserted before tx data. In Frame Relay protocol,
|
||||
* the tx x25 header is not used, thus it can be
|
||||
* set to zero */
|
||||
|
||||
api_tx_el = (api_tx_element_t *)Tx_data;
|
||||
|
||||
/* Fill in the packet data */
|
||||
for (i=0; i<Tx_length ; i++){
|
||||
*((unsigned char *)&api_tx_el->data + i) = (unsigned char) i;
|
||||
}
|
||||
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&writeset);
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
|
||||
#ifdef WRITE
|
||||
FD_SET(sock,&writeset);
|
||||
#endif
|
||||
FD_SET(sock,&readset);
|
||||
FD_SET(sock,&oobset);
|
||||
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active sockets.
|
||||
*/
|
||||
|
||||
if(select(sock + 1, &readset, &writeset, &oobset, NULL)){
|
||||
|
||||
|
||||
/* Check if the socket is ready to tx data */
|
||||
|
||||
if (FD_ISSET(sock,&writeset)){
|
||||
|
||||
err = send(sock, Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err > 0) {
|
||||
/* Packet sent ok */
|
||||
printf("Packet Sent %i, length = %i\n",
|
||||
++Tx_count, Tx_length);
|
||||
}else{
|
||||
/* The driver is busy, we must requeue this
|
||||
* tx packet, and try resending it again
|
||||
* later. */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock,&readset)){
|
||||
|
||||
err = recv(sock,Rx_data, Rx_length + sizeof(api_rx_hdr_t),0);
|
||||
|
||||
if (err < 0){
|
||||
/* This should never happen. If it does the
|
||||
* socket is corrupted. Thus exit.*/
|
||||
printf("Failed to rec %i , %i\n", Rx_count, err);
|
||||
break;
|
||||
}else{
|
||||
/* Rx packet recevied OK
|
||||
* Each rx packet will contain 16 bytes of
|
||||
* rx header, that must be removed. The
|
||||
* first byte of the 16 byte header will
|
||||
* indicate an error condition.
|
||||
*/
|
||||
|
||||
api_rx_el = (api_rx_element_t*)Rx_data;
|
||||
|
||||
/* The data portion of the api_rx_el
|
||||
* contains the real data.
|
||||
|
||||
api_rx_el->data
|
||||
|
||||
*/
|
||||
|
||||
printf("Packet receive %i, length = %i\n",
|
||||
++Rx_count, err);
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop after number of frames */
|
||||
if(Tx_count == NO_FRMS_TO_TX)
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
close(sock);
|
||||
}
|
|
@ -0,0 +1,504 @@
|
|||
/*****************************************************************************
|
||||
* lib_api.c Common API library
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 2003 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
#include <linux/wanpipe_defines.h>
|
||||
#include <linux/wanpipe_cfg.h>
|
||||
#include <linux/wanpipe.h>
|
||||
|
||||
#include "lib_api.h"
|
||||
|
||||
#define SINGLE_CHANNEL 0x2
|
||||
#define RANGE_CHANNEL 0x1
|
||||
|
||||
|
||||
char read_enable=0;
|
||||
char write_enable=0;
|
||||
char primary_enable=0;
|
||||
int tx_cnt=1;
|
||||
int rx_cnt=0;
|
||||
int tx_size=10;
|
||||
int tx_delay=0;
|
||||
int tx_data=-1;
|
||||
|
||||
unsigned char card_name[WAN_IFNAME_SZ];
|
||||
unsigned char if_name[WAN_IFNAME_SZ];
|
||||
|
||||
unsigned char sw_if_name[WAN_IFNAME_SZ];
|
||||
unsigned char sw_card_name[WAN_IFNAME_SZ];
|
||||
|
||||
unsigned char tx_file[WAN_IFNAME_SZ];
|
||||
unsigned 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];
|
||||
|
||||
int files_used=0;
|
||||
int verbose=0;
|
||||
|
||||
int tx_connections;
|
||||
|
||||
int ds_prot=0;
|
||||
int ds_prot_opt=0;
|
||||
int ds_max_mult_cnt=0;
|
||||
unsigned int ds_active_ch=0;
|
||||
int ds_7bit_hdlc=0;
|
||||
int direction=-1;
|
||||
|
||||
int tx_channels=1;
|
||||
int cause=0;
|
||||
int diagn=0;
|
||||
|
||||
int card_cnt=0;
|
||||
int i_cnt=0;
|
||||
|
||||
unsigned long parse_active_channel(char* val);
|
||||
|
||||
int init_args(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
int c_cnt=0;
|
||||
|
||||
sprintf(daddr,"111");
|
||||
sprintf(saddr,"222");
|
||||
sprintf(udata,"C9");
|
||||
|
||||
for (i = 0; i < argc; i++){
|
||||
|
||||
if (!strcmp(argv[i],"-i")){
|
||||
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid Interface Name!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
strncpy(if_name, argv[i+1],WAN_IFNAME_SZ);
|
||||
i_cnt=1;
|
||||
|
||||
}else if (!strcmp(argv[i],"-si")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid Switch Interface Name!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
strncpy(sw_if_name, argv[i+1], WAN_IFNAME_SZ);
|
||||
|
||||
}else if (!strcmp(argv[i],"-c")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid Card Name!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
strncpy(card_name, argv[i+1], WAN_IFNAME_SZ);
|
||||
card_cnt=1;
|
||||
|
||||
}else if (!strcmp(argv[i],"-sc")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid Switch Card Name!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
strncpy(sw_card_name, argv[i+1], WAN_IFNAME_SZ);
|
||||
|
||||
}else if (!strcmp(argv[i],"-r")){
|
||||
read_enable=1;
|
||||
c_cnt=1;
|
||||
|
||||
}else if (!strcmp(argv[i],"-w")){
|
||||
write_enable=1;
|
||||
c_cnt=1;
|
||||
|
||||
}else if (!strcmp(argv[i],"-pri")){
|
||||
primary_enable=1;
|
||||
|
||||
}else if (!strcmp(argv[i],"-txcnt")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid tx cnt!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
tx_cnt = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid tx cnt!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
}else if (!strcmp(argv[i],"-rxcnt")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid rx cnt!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
rx_cnt = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid rx cnt!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
}else if (!strcmp(argv[i],"-txsize")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid tx size!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
tx_size = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid tx size, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
}else if (!strcmp(argv[i],"-txdelay")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid tx delay!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
tx_delay = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid tx delay, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
}else if (!strcmp(argv[i],"-txdata")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid tx data!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
tx_data = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid tx data, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
}else if (!strcmp(argv[i],"-txfile")){
|
||||
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid Tx File Name!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
strncpy(tx_file, argv[i+1],WAN_IFNAME_SZ);
|
||||
files_used |= TX_FILE_USED;
|
||||
|
||||
}else if (!strcmp(argv[i],"-rxfile")){
|
||||
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid Rx File Name!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
strncpy(rx_file, argv[i+1],WAN_IFNAME_SZ);
|
||||
files_used |= RX_FILE_USED;
|
||||
|
||||
}else if (!strcmp(argv[i],"-daddr")){
|
||||
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid daddr str!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
strncpy(daddr, argv[i+1],TX_ADDR_STR_SZ);
|
||||
|
||||
}else if (!strcmp(argv[i],"-saddr")){
|
||||
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid saddr str!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
strncpy(saddr, argv[i+1],TX_ADDR_STR_SZ);
|
||||
|
||||
}else if (!strcmp(argv[i],"-udata")){
|
||||
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid udata str!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
strncpy(udata, argv[i+1],TX_ADDR_STR_SZ);
|
||||
|
||||
}else if (!strcmp(argv[i],"-verbose")){
|
||||
verbose=1;
|
||||
|
||||
}else if (!strcmp(argv[i],"-prot")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid prot!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
ds_prot = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid prot, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
|
||||
}else if (!strcmp(argv[i],"-prot_opt")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid prot_opt!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
ds_prot_opt = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid prot_opt, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
}else if (!strcmp(argv[i],"-max_mult_cnt")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid max_mult_cnt!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
ds_max_mult_cnt = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid max_mult_cnt, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
}else if (!strcmp(argv[i],"-active_ch")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid active ch!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
ds_active_ch = parse_active_channel(argv[i+1]);
|
||||
}else if (!strcmp(argv[i],"-txchan")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid channels!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
tx_channels = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid channels, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
}else if (!strcmp(argv[i],"-diagn")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid diagn!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
diagn = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid diagn, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
}else if (!strcmp(argv[i],"-cause")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid cause!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
cause = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid cause, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
}else if (!strcmp(argv[i],"-7bit_hdlc")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid 7bit hdlc value!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
ds_7bit_hdlc = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid 7bit hdlc, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
}else if (!strcmp(argv[i],"-dir")){
|
||||
if (i+1 > argc-1){
|
||||
printf("ERROR: Invalid direction value!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
if(isdigit(argv[i+1][0])){
|
||||
direction = atoi(argv[i+1]);
|
||||
}else{
|
||||
printf("ERROR: Invalid direction, must be a digit!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!i_cnt){
|
||||
printf("ERROR: No Interface Name!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
if (!card_cnt){
|
||||
printf("ERROR: No Card name!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
if (!c_cnt){
|
||||
printf("ERROR: No Read or Write Command!\n");
|
||||
return WAN_FALSE;
|
||||
}
|
||||
|
||||
return WAN_TRUE;
|
||||
}
|
||||
|
||||
static unsigned char api_usage[]="\n"
|
||||
"\n"
|
||||
"<options>:\n"
|
||||
" -i <ifname> #interface name\n"
|
||||
" -c <card name> #card name\n"
|
||||
" -r #read enable\n"
|
||||
" -w #write eable\n"
|
||||
"\n"
|
||||
"<extra options>\n"
|
||||
" -txcnt <digit> #number of tx packets (Dflt: 1)\n"
|
||||
" -txsize <digit> #tx packet size (Dflt: 10)\n"
|
||||
" -txdelay <digit> #delay in sec after each tx packet (Dflt: 0)\n"
|
||||
" -txdata <digit> #data to tx <1-255>\n"
|
||||
"\n"
|
||||
" -txfile <file> #Use file to tx instead\n"
|
||||
" -rxfile <file> #Save all rx data to a file\n"
|
||||
" \n"
|
||||
" -rxcnt <digit> #number of rx packets before exit\n"
|
||||
" #this number overwrites the txcnt\n"
|
||||
" #Thus, app will only exit after it\n"
|
||||
" #receives the rxcnt number of packets.\n"
|
||||
" \n"
|
||||
" -verbose #Enable verbose mode\n"
|
||||
"\n"
|
||||
"<datascope options>\n"
|
||||
"\n"
|
||||
" -prot <digit> #Protocol Bit map: \n"
|
||||
" #1=FISU, 2=LSSU, 4=MSU, 8=RAW HDLC\n"
|
||||
" \n"
|
||||
" -prot_opt <digit> #Protocol bit map\n"
|
||||
" #0=None, 1=Delta, 2=Max Multiple\n"
|
||||
"\n"
|
||||
" -active_ch <digit> #Active channel\n"
|
||||
" #ALL = all channels \n"
|
||||
" #1 24 = 1 to 24 \n"
|
||||
" #1.24 = 1 and 24 \n"
|
||||
" #1-4.7-15 = 1 to 4 and 7 to 15\n"
|
||||
" \n"
|
||||
" -max_mult_cnt <digit> #If Prot_opt == 2 \n"
|
||||
" #max_mult_cnt is the number of \n"
|
||||
" #consecutive duplicate frames \n"
|
||||
" #received before pass up the stack.\n"
|
||||
" \n"
|
||||
" -7bit_hdlc <digit> #Enable 7 Bit Hdlc Engine\n"
|
||||
" #1=Enable 0=Disable\n"
|
||||
" \n"
|
||||
" -dir <digit> #Direction 0: Rx 1: Tx none: All\n"
|
||||
"\n"
|
||||
"<x25 protocol options>\n"
|
||||
"\n"
|
||||
" -txchan <digit> #Number of channels (dflt=1)\n"
|
||||
" -cause <digit> #disconnect cause (dflt=0)\n"
|
||||
" -diagn <digit> #disconnect diagnostic (dflt=0)\n"
|
||||
"\n";
|
||||
|
||||
void usage(unsigned char *api_name)
|
||||
{
|
||||
printf ("\n\nAPI %s USAGE:\n\n%s <options> <extra options>\n\n%s\n",
|
||||
api_name,api_name,api_usage);
|
||||
}
|
||||
|
||||
|
||||
/*============================================================================
|
||||
* TE1
|
||||
*/
|
||||
unsigned long get_active_channels(int channel_flag, int start_channel, int stop_channel)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned long tmp = 0, mask = 0;
|
||||
|
||||
if ((channel_flag & (SINGLE_CHANNEL | RANGE_CHANNEL)) == 0)
|
||||
return tmp;
|
||||
if (channel_flag & RANGE_CHANNEL) { /* Range of channels */
|
||||
for(i = start_channel; i <= stop_channel; i++) {
|
||||
mask = 1 << (i - 1);
|
||||
tmp |=mask;
|
||||
}
|
||||
} else { /* Single channel */
|
||||
mask = 1 << (stop_channel - 1);
|
||||
tmp |= mask;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
unsigned long parse_active_channel(char* val)
|
||||
{
|
||||
int channel_flag = 0;
|
||||
char* ptr = val;
|
||||
int channel = 0, start_channel = 0;
|
||||
unsigned long tmp = 0;
|
||||
|
||||
if (strcmp(val,"ALL") == 0)
|
||||
return ENABLE_ALL_CHANNELS;
|
||||
|
||||
while(*ptr != '\0') {
|
||||
if (isdigit(*ptr)) {
|
||||
channel = strtoul(ptr, &ptr, 10);
|
||||
channel_flag |= SINGLE_CHANNEL;
|
||||
} else {
|
||||
if (*ptr == '-') {
|
||||
channel_flag |= RANGE_CHANNEL;
|
||||
start_channel = channel;
|
||||
} else {
|
||||
tmp |= get_active_channels(channel_flag, start_channel, channel);
|
||||
channel_flag = 0;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
if (channel_flag){
|
||||
tmp |= get_active_channels(channel_flag, start_channel, channel);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void u_delay(int usec)
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_usec = usec;
|
||||
tv.tv_sec=0;
|
||||
|
||||
select(0,NULL,NULL, NULL, &tv);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*****************************************************************************
|
||||
* lib_api.h Common API library
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 2003 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.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
|
||||
extern char read_enable;
|
||||
extern char write_enable;
|
||||
extern char primary_enable;
|
||||
extern int tx_cnt;
|
||||
extern int rx_cnt;
|
||||
extern int tx_size;
|
||||
extern int tx_delay;
|
||||
extern int tx_data;
|
||||
extern int files_used;
|
||||
extern int verbose;
|
||||
extern int ds_prot;
|
||||
extern int ds_prot_opt;
|
||||
extern int ds_max_mult_cnt;
|
||||
extern unsigned int ds_active_ch;
|
||||
extern int ds_7bit_hdlc;
|
||||
extern int direction;
|
||||
|
||||
extern int tx_channels;
|
||||
extern int diagn;
|
||||
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];
|
||||
|
||||
#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];
|
||||
|
||||
|
||||
#define TX_FILE_USED 1
|
||||
#define RX_FILE_USED 2
|
||||
|
||||
|
||||
|
||||
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 unsigned char sw_if_name[WAN_IFNAME_SZ];
|
||||
extern unsigned char sw_card_name[WAN_IFNAME_SZ];
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* These are the public elements of the Linux DSP module.
|
||||
*/
|
||||
|
||||
#ifndef _WANPIPE_DSP_KERNEL_H
|
||||
#define _WANPIPE_DSP_KERNEL_H
|
||||
|
||||
/*
|
||||
* ******************************************************************
|
||||
* INCLUDES *
|
||||
* ******************************************************************
|
||||
*/
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <linux/wanpipe_cfg.h>
|
||||
#include "wanpipe_x25_kernel.h"
|
||||
|
||||
/*
|
||||
* ******************************************************************
|
||||
* DEFINES/MACROS *
|
||||
* ******************************************************************
|
||||
*/
|
||||
|
||||
/* DSP Messages */
|
||||
#define DSP_CALL_REQ_HOST_MSG 0x56
|
||||
#define DSP_CALL_REQ_TERM_MSG 0x57
|
||||
#define DSP_INV_TO_CLEAR_MSG 0x01
|
||||
#define DSP_CMD_RES_UNDELIVERED_MSG 0x10
|
||||
#define DSP_CMD_RES_ABORTED_MSG 0x11
|
||||
#define DSP_STATUS_MSG 0x12
|
||||
#define DSP_ACK_MSG 0x14
|
||||
#define DSP_CIRCUIT_ENABLED_MSG 0x20
|
||||
#define DSP_CIRCUIT_RESET_MSG 0x21
|
||||
#define DSP_CIRCUIT_REQUEST_MSG 0x22
|
||||
#define DSP_CIRCUIT_DISCONNECT_MSG 0x24
|
||||
|
||||
#define DSP_DATA_MSG 0x40
|
||||
#define DSP_DATA_ACK_MSG 0x41
|
||||
|
||||
|
||||
#define DSP_FALSE 0
|
||||
#define DSP_TRUE 1
|
||||
|
||||
#define DSP_OK 0
|
||||
|
||||
/* 'dsp_result' values */
|
||||
#define DSP_LINK_DOWN 0x01
|
||||
#define DSP_LINK_READY 0x02
|
||||
#define DSP_LINK_RESET 0x03
|
||||
|
||||
/* Options for 'DSP_pad' */
|
||||
#define DSP_HPAD 0x00
|
||||
#define DSP_TPAD 0x01
|
||||
|
||||
#define DSP_MAX_DATA 1024
|
||||
|
||||
#define DSP_CALL_STR_SZ 512
|
||||
|
||||
#ifndef DSP_PROT
|
||||
# define DSP_PROT 0x20
|
||||
#endif
|
||||
|
||||
/* Control Byte */
|
||||
#define DSP_CR_INC_INF_FOR_SE 0x01 /* Further information for session
|
||||
* establishment is contained in a
|
||||
* CIRCUIT REQEUST message
|
||||
*/
|
||||
#define DSP_SND_MULT_USER_CR 0x02 /* Sends a Multiple User Circuit
|
||||
* Request message.
|
||||
*/
|
||||
#define DSP_TT_SUPPORTS 0x04 /* Request is for a 3270 device that
|
||||
* supports Transparent Text.
|
||||
*/
|
||||
#define DSP_REQ_FOR_ASCII_DEV 0x08 /* Request is for an ASCII device.
|
||||
*/
|
||||
|
||||
/* Connection Request Mode */
|
||||
#define DSP_CRM_TYPE1 0x01 /* Referred to as fixed class */
|
||||
#define DSP_CRM_TYPE2 0x02 /* Referred to as specific class */
|
||||
#define DSP_CRM_TYPE3 0x03 /* Referred to as non-specific class */
|
||||
#define DSP_CRM_TYPE4 0x04 /* Referred to as associated class */
|
||||
|
||||
/*
|
||||
* *************
|
||||
* Reason Code *
|
||||
* *************
|
||||
*/
|
||||
/* Reason code for CIRCUIT_RESET */
|
||||
#define DSP_RC_RESET 0x00
|
||||
#define DSP_RC_DATA_ERROR 0x11
|
||||
/* Reason code for INVITATION_TO_CLEAR */
|
||||
#define DSP_RC_UNDEFINED 0x00
|
||||
#define DSP_RC_USER 0x01
|
||||
#define DSP_RC_INVALID_DQ_MSG 0x10
|
||||
#define DSP_RC_INVALID_STATE_TRANS 0x11
|
||||
#define DSP_RC_INVALID_DQ_FORMAT 0x12
|
||||
#define DSP_RC_INVALID_DATA_FORMAT 0x13
|
||||
#define DSP_RC_TIMEOUT 0x20
|
||||
#define DSP_RC_FACILITY_FAILURE 0x21
|
||||
|
||||
/*
|
||||
* ******************************************************************
|
||||
* ENUM/TYPEDEF/STRCTURE *
|
||||
* ******************************************************************
|
||||
*/
|
||||
enum {
|
||||
SIOC_DSP_PLACE_CALL = (SIOC_ANNEXG_PLACE_CALL),
|
||||
SIOC_DSP_CLEAR_CALL = (SIOC_ANNEXG_CLEAR_CALL),
|
||||
SIOC_DSP_API_RESERVED = (SIOC_WANPIPE_DEVPRIVATE),
|
||||
|
||||
SIOC_DSP_GET_CALL_DATA,
|
||||
SIOC_DSP_SET_CALL_DATA,
|
||||
|
||||
SIOC_DSP_ACCEPT_CALL,
|
||||
SIOC_DSP_RESET_CALL,
|
||||
SIOC_DSP_DEBUG,
|
||||
|
||||
SIOC_DSP_INVITATION_TO_CLEAR,
|
||||
SIOC_DSP_CIRCUIT_ENABLED,
|
||||
SIOC_DSP_CIRCUIT_RESET,
|
||||
SIOC_DSP_CIRCUIT_DISCONNECT,
|
||||
SIOC_DSP_CIRCUIT_REQUEST,
|
||||
SIOC_DSP_STATUS,
|
||||
SIOC_DSP_ACK,
|
||||
SIOC_DSP_CMD_RES_UNDELIVERED,
|
||||
SIOC_DSP_CMD_RES_ABORTED,
|
||||
|
||||
SIOC_DSP_SEND_DATA,
|
||||
SIOC_DSP_RECEIVE_DATA,
|
||||
|
||||
SIOC_DSP_SET_PID,
|
||||
SIOC_DSP_SET_LCN_LABEL
|
||||
};
|
||||
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
unsigned char dsp_pkt_type; /* DSP packet type */
|
||||
unsigned char dsp_resp; /* 1 - sending response */
|
||||
unsigned char dsp_user_cn; /* user circuit number */
|
||||
unsigned short dsp_length; /* Data length */
|
||||
unsigned short dsp_lcn;
|
||||
unsigned char dsp_result;
|
||||
union {
|
||||
unsigned char status; /* Status */
|
||||
unsigned char pad_type; /* PAD type */
|
||||
#if 0
|
||||
ALEX 10.4.2001
|
||||
ETX_ETB_ESC
|
||||
unsigned char et_byte; /* ET byte (1-ETX,0-ETB)*/
|
||||
#endif
|
||||
} dspapi_hdr_dspu1;
|
||||
union {
|
||||
struct {
|
||||
unsigned char src_cu_addr; /* Src Ctrl Unit addr */
|
||||
unsigned char src_dev_addr; /* Source Device addr */
|
||||
unsigned char ctrl_byte; /* control byte */
|
||||
unsigned char dev_info; /* Device information */
|
||||
unsigned char crm_type; /* Con. Request mode */
|
||||
} dspapi_hdr_dsppc1;
|
||||
unsigned char error_code; /* Sense byte */
|
||||
unsigned char reason_code; /* reason code */
|
||||
unsigned char transp; /* Transparent data */
|
||||
} dspapi_hdr_dspu2;
|
||||
union {
|
||||
struct {
|
||||
unsigned char dst_cu_addr; /* Dst Ctrl Unit addr */
|
||||
unsigned char dst_dev_addr; /* Dst Device addr */
|
||||
}dspapi_hdr_dsppc2;
|
||||
unsigned char sn; /* seq. num */
|
||||
unsigned char sense; /* Sense byte */
|
||||
}dspapi_hdr_dspu3;
|
||||
}dspapi_hdr_t;
|
||||
|
||||
#define dsp_status dspapi_hdr_dspu1.status
|
||||
#define dsp_pad_type dspapi_hdr_dspu1.pad_type
|
||||
#define dsp_et_byte dspapi_hdr_dspu1.et_byte
|
||||
|
||||
#define dsp_src_cu_addr dspapi_hdr_dspu2.dspapi_hdr_dsppc1.src_cu_addr
|
||||
#define dsp_src_dev_addr dspapi_hdr_dspu2.dspapi_hdr_dsppc1.src_dev_addr
|
||||
#define dsp_ctrl_byte dspapi_hdr_dspu2.dspapi_hdr_dsppc1.ctrl_byte
|
||||
#define dsp_dev_info dspapi_hdr_dspu2.dspapi_hdr_dsppc1.dev_info
|
||||
#define dsp_crm_type dspapi_hdr_dspu2.dspapi_hdr_dsppc1.crm_type
|
||||
#define dsp_error_code dspapi_hdr_dspu2.error_code
|
||||
#define dsp_reason_code dspapi_hdr_dspu2.reason_code
|
||||
#define dsp_data_transp dspapi_hdr_dspu2.transp
|
||||
|
||||
#define dsp_dst_cu_addr dspapi_hdr_dspu3.dspapi_hdr_dsppc2.dst_cu_addr
|
||||
#define dsp_dst_dev_addr dspapi_hdr_dspu3.dspapi_hdr_dsppc2.dst_dev_addr
|
||||
#define dsp_sense dspapi_hdr_dspu3.sense
|
||||
#define dsp_sn dspapi_hdr_dspu3.sn
|
||||
|
||||
typedef struct {
|
||||
dspapi_hdr_t hdr;
|
||||
char data[DSP_MAX_DATA];
|
||||
}dspapi_t;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
struct wanpipe_dsp_register_struct{
|
||||
unsigned char init;
|
||||
int (*dsp_bind_api)(struct net_device *master_dev, void *sk_id);
|
||||
};
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Return codes from interface commands
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
extern int register_wanpipe_dsp_protocol(struct wanpipe_dsp_register_struct*);
|
||||
extern void unregister_wanpipe_dsp_protocol(void);
|
||||
|
||||
extern int register_x25_dsp_protocol(struct x25_dsp_register_struct*);
|
||||
extern void unregister_x25_dsp_protocol(void);
|
||||
extern struct net_device* x25_get_svc_dev(struct net_device* master_dev);
|
||||
extern int x25_get_call_info(struct net_device* master_dev, unsigned short*, unsigned short*, unsigned short*);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* These are the public elements of the Linux LAPB module.
|
||||
*/
|
||||
|
||||
#include <linux/wanpipe_debug.h>
|
||||
#include <linux/wanpipe_cfg.h>
|
||||
#include <linux/if_wanpipe_common.h>
|
||||
#include "wanpipe_x25_kernel.h"
|
||||
|
||||
#ifndef LAPB_KERNEL_H
|
||||
#define LAPB_KERNEL_H
|
||||
|
||||
#define LAPB_OK 0
|
||||
#define LAPB_BADTOKEN 1
|
||||
#define LAPB_INVALUE 2
|
||||
#define LAPB_CONNECTED 3
|
||||
#define LAPB_NOTCONNECTED 4
|
||||
#define LAPB_REFUSED 5
|
||||
#define LAPB_TIMEDOUT 6
|
||||
#define LAPB_NOMEM 7
|
||||
|
||||
#define LAPB_STANDARD 0x00
|
||||
#define LAPB_EXTENDED 0x01
|
||||
|
||||
#define LAPB_SLP 0x00
|
||||
#define LAPB_MLP 0x02
|
||||
|
||||
#define LAPB_DTE 0x00
|
||||
#define LAPB_DCE 0x04
|
||||
|
||||
enum lapb_ioctl_cmds {
|
||||
SIOCC_PC_RESERVED = (SIOCDEVPRIVATE),
|
||||
SIOCG_LAPB_CONF,
|
||||
SIOCS_LAPB_NEW_X25_CONF,
|
||||
SIOCS_LAPB_DEL_X25_CONF,
|
||||
SIOCG_LAPB_STATUS,
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern int register_lapb_x25_protocol (struct lapb_x25_register_struct * x25_reg);
|
||||
extern void unregister_lapb_x25_protocol (void);
|
||||
|
||||
|
||||
extern int lapb_x25_register(struct net_device *lapb_dev,
|
||||
char *dev_name,
|
||||
struct net_device **new_dev);
|
||||
|
||||
extern int lapb_x25_unregister(struct net_device *x25_dev);
|
||||
|
||||
extern int lapb_x25_setparms (struct net_device *lapb_dev,
|
||||
struct net_device *x25_dev,
|
||||
struct x25_parms_struct *x25_parms);
|
||||
|
||||
|
||||
struct wanpipe_lapb_register_struct {
|
||||
|
||||
unsigned long init;
|
||||
|
||||
int (*lapb_register)(struct net_device *dev,
|
||||
char *dev_name, char *hw_name,
|
||||
struct net_device **new_dev);
|
||||
int (*lapb_unregister)(struct net_device *dev);
|
||||
|
||||
int (*lapb_getparms)(struct net_device *dev, struct lapb_parms_struct *parms);
|
||||
int (*lapb_setparms)(struct net_device *dev, struct lapb_parms_struct *parms);
|
||||
void (*lapb_mark_bh) (struct net_device *dev);
|
||||
void (*lapb_link_up) (struct net_device *dev);
|
||||
void (*lapb_link_down) (struct net_device *dev);
|
||||
int (*lapb_rx) (struct net_device *dev, struct sk_buff *skb);
|
||||
|
||||
int (*lapb_x25_register)(struct net_device *lapb_dev,
|
||||
char *dev_name,
|
||||
struct net_device **new_dev);
|
||||
|
||||
int (*lapb_x25_unregister)(struct net_device *x25_dev);
|
||||
|
||||
int (*lapb_x25_setparms) (struct net_device *lapb_dev,
|
||||
struct net_device *x25_dev,
|
||||
struct x25_parms_struct *x25_parms);
|
||||
int (*lapb_get_map)(struct net_device*, struct seq_file *);
|
||||
void (*lapb_get_active_inactive)(struct net_device*, wp_stack_stats_t*);
|
||||
};
|
||||
|
||||
extern int register_wanpipe_lapb_protocol (struct wanpipe_lapb_register_struct *lapb_reg);
|
||||
extern void unregister_wanpipe_lapb_protocol (void);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,376 @@
|
|||
/*
|
||||
* These are the public elements of the Linux X25 module.
|
||||
*/
|
||||
|
||||
#ifndef WANPIPE_X25_KERNEL_H
|
||||
#define WANPIPE_X25_KERNEL_H
|
||||
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <linux/wanpipe_debug.h>
|
||||
#include <linux/wanpipe_cfg.h>
|
||||
#include <linux/if_wanpipe_common.h>
|
||||
|
||||
#define X25_OK 0
|
||||
#define X25_BADTOKEN 1
|
||||
#define X25_INVALUE 2
|
||||
#define X25_CONNECTED 3
|
||||
#define X25_NOTCONNECTED 4
|
||||
#define X25_REFUSED 5
|
||||
#define X25_TIMEDOUT 6
|
||||
#define X25_NOMEM 7
|
||||
|
||||
#define X25_STANDARD 0x00
|
||||
#define X25_EXTENDED 0x01
|
||||
|
||||
#define X25_SLP 0x00
|
||||
#define X25_MLP 0x02
|
||||
|
||||
#define X25_DTE 0x00
|
||||
#define X25_DCE 0x04
|
||||
|
||||
#define WAN_ADDRESS_SZ 31
|
||||
#define X25_CALL_STR_SZ 512
|
||||
#define WAN_IF_LABEL_SZ 15
|
||||
|
||||
#define M_BIT 1
|
||||
#define CLEAR_NO_WAIT 0x00
|
||||
#define CLEAR_WAIT_FOR_DATA 0x80
|
||||
|
||||
/* X.25 packet types */
|
||||
#define DATA_PKT 0x00
|
||||
#define RR_PKT 0x01
|
||||
#define RNR_PKT 0x05
|
||||
#define REJ_PKT 0x09
|
||||
#define CALL_REQUEST_PKT 0x0B
|
||||
#define CALL_ACCEPT_PKT 0x0F
|
||||
#define CLEAR_REQUEST_PKT 0x13
|
||||
#define CLEAR_CONF_PKT 0x17
|
||||
#define RESET_REQUEST_PKT 0x1B
|
||||
#define RESET_CONF_PKT 0x1F
|
||||
#define RESTART_REQUEST_PKT 0xFB
|
||||
#define RESTART_CONF_PKT 0xFF
|
||||
#define INTERRUPT_PKT 0x23
|
||||
#define INTERRUPT_CONF_PKT 0x27
|
||||
#define DIAGNOSTIC_PKT 0xF1
|
||||
#define REGISTRATION_REQUEST_PKT 0xF3
|
||||
#define REGISTRATION_CONF_PKT 0xF7
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
SIOC_X25_PLACE_CALL = (SIOC_ANNEXG_PLACE_CALL),
|
||||
SIOC_X25_CLEAR_CALL = (SIOC_ANNEXG_CLEAR_CALL),
|
||||
SIOC_X25_API_RESERVED = (SIOC_WANPIPE_DEVPRIVATE),
|
||||
|
||||
SIOC_X25_GET_CALL_DATA,
|
||||
SIOC_X25_SET_CALL_DATA,
|
||||
|
||||
SIOC_X25_ACCEPT_CALL,
|
||||
SIOC_X25_RESET_CALL,
|
||||
SIOC_X25_DEBUG,
|
||||
SIOC_X25_SET_LCN_PID,
|
||||
SIOC_X25_SET_LCN_LABEL,
|
||||
SIOC_X25_INTERRUPT
|
||||
};
|
||||
|
||||
|
||||
#define SIOC_WANPIPE_GET_CALL_DATA SIOC_X25_GET_CALL_DATA
|
||||
#define SIOC_WANPIPE_SET_CALL_DATA SIOC_X25_SET_CALL_DATA
|
||||
#define SIOC_WANPIPE_ACCEPT_CALL SIOC_X25_ACCEPT_CALL
|
||||
#define SIOC_WANPIPE_CLEAR_CALL SIOC_X25_CLEAR_CALL
|
||||
#define SIOC_WANPIPE_RESET_CALL SIOC_X25_RESET_CALL
|
||||
#define SIOC_WANPIPE_INTERRUPT SIOC_X25_INTERRUPT
|
||||
|
||||
|
||||
#define DECODE_X25_CMD(cmd) ((cmd==SIOC_X25_PLACE_CALL)?"X25 PLACE CALL" : \
|
||||
(cmd==SIOC_X25_CLEAR_CALL)?"X25 CLEAR CALL" : \
|
||||
(cmd==SIOC_X25_GET_CALL_DATA)?"X25 GET CALL" : \
|
||||
(cmd==SIOC_X25_SET_CALL_DATA)?"X25 SET CALL" : \
|
||||
(cmd==SIOC_X25_ACCEPT_CALL)?"X25 ACCEPT CALL" : \
|
||||
(cmd==SIOC_X25_RESET_CALL)?"X25 RESET CALL" : \
|
||||
(cmd==SIOC_X25_DEBUG)?"X25 DEBUG" : \
|
||||
(cmd==SIOC_X25_INTERRUPT)?"X25 INTERRUPT" : \
|
||||
(cmd==SIOC_X25_SET_LCN_PID)?"X25 SET PID": \
|
||||
(cmd==SIOC_X25_SET_LCN_LABEL)?"X25 SET LABEL" : DECODE_API_CMD(cmd) )
|
||||
|
||||
|
||||
|
||||
/*============ bit settings for the 'X25_API_options' ============ */
|
||||
|
||||
/* don't check the transmit window of the LCN when transmitting data */
|
||||
#define DONT_CHK_TX_WIN_ON_DATA_TX 0x0001
|
||||
|
||||
/*========== bit settings for the 'X25_protocol_options' byte =========*/
|
||||
|
||||
/* registration pragmatics supported */
|
||||
#define REGISTRATION_PRAGMATICS_SUPP 0x0001
|
||||
/* a station configured as a DCE will issue Diagnostic packets */
|
||||
#define NO_DIAG_PKTS_ISSUED_BY_DCE 0x0002
|
||||
/* a Restart Request packet is not issued when entering the ABM */
|
||||
#define NO_RESTART_REQ_ON_ENTER_ABM 0x0004
|
||||
/* an asynchronous packet does not include a diagnostic field */
|
||||
#define NO_DIAG_FIELD_IN_ASYNC_PKTS 0x0008
|
||||
/* D-bit pragmatics are not supported */
|
||||
#define D_BIT_PRAGMATICS_NOT_SUPPORTED 0x0010
|
||||
/* flow control facilities are automatically inserted in call */
|
||||
#define AUTO_FLOW_CTRL_PARM_FACIL_INS 0x0020
|
||||
/* setup packets */
|
||||
#define CALLAC_DOES_NOT_INCL_ADDR_LGTH 0x0040 /* a transmitted or received Call Accept packet does not include */
|
||||
/* an address and facilities length field */
|
||||
#define HANDLE_ALL_INCOMING_FACILS 0x0080 /* all incoming facilities are supported */
|
||||
#define NO_CHK_PROC_INCOMING_FACILS 0x0100 /* incoming facilities are not checked and processed */
|
||||
|
||||
/* bit settings for the 'X25_response_options' byte */
|
||||
#define ALL_DATA_PKTS_ACKED_WITH_RR 0x0001 /* all received Data packets are acknowledged with an RR */
|
||||
#define DISABLE_AUTO_CLEAR_CONF 0x0002 /* disable the automatic issing of Clear Confirmation packets */
|
||||
#define DISABLE_AUTO_RESET_CONF 0x0004 /* disable the automatic issing of Reset Confirmation packets */
|
||||
#define DISABLE_AUTO_RESTART_CONF 0x0008 /* disable the automatic issing of Restart Confirmation packets */
|
||||
#define DISABLE_AUTO_INT_CONF 0x0010 /* disable the automatic issing of Interrupt Confirmation packets */
|
||||
|
||||
/* 'genl_facilities_supported_1' */
|
||||
#define FLOW_CTRL_PARM_NEG_SUPP 0x0001
|
||||
#define THROUGHPUT_CLASS_NEG_SUPP 0x0002
|
||||
#define REV_CHARGING_SUPP 0x0004
|
||||
#define FAST_SELECT_SUPP 0x0008
|
||||
#define NUI_SELECTION_SUPP 0x0010
|
||||
#define CUG_SELECT_BASIC_SUPP 0x0020
|
||||
#define CUG_SELECT_EXT_SUPP 0x0040
|
||||
#define CUG_OUT_ACC_SEL_BASIC_SUPP 0x0080
|
||||
#define CUG_OUT_ACC_SEL_EXT_SUPP 0x0100
|
||||
#define BI_CUG_SEL_SUPP 0x0200
|
||||
#define RPOA_SEL_BASIC_FORMAT_SUPP 0x0400
|
||||
#define RPOA_SEL_EXT_FORMAT_SUPP 0x0800
|
||||
#define CALL_DEFLEC_SEL_SUPP 0x1000
|
||||
#define CALL_REDIR_DEFLEC_NOTIF_SUPP 0x2000
|
||||
#define CALLED_LNE_ADDR_MOD_NOTIF_SUPP 0x4000
|
||||
#define TRANSIT_DELAY_SELECT_IND_SUPP 0x8000
|
||||
|
||||
/* 'genl_facilities_supported_2' */
|
||||
#define CHRG_INFO_REQ_SERVICE_SUPP 0x0001
|
||||
#define CHRG_INFO_IND_MON_UNIT_SUPP 0x0002
|
||||
#define CHRG_INFO_IND_SEG_COUNT_SUPP 0x0004
|
||||
#define CHRG_INFO_IND_CALL_DUR_SUPP 0x0008
|
||||
|
||||
/* 'CCITT_facilities_supported' */
|
||||
#define CCITT_CALLING_ADDR_EXT_SUPP 0x0001
|
||||
#define CCITT_CALLED_ADDR_EXT_SUPP 0x0002
|
||||
#define CCITT_MIN_THROUGH_CLS_NEG_SUPP 0x0004
|
||||
#define CCITT_ETE_TX_DELAY_NEG_SUPP 0x0008
|
||||
#define CCITT_PRIORITY_SUPP 0x0010
|
||||
#define CCITT_PROTECTION_SUPP 0x0020
|
||||
#define CCITT_EXPIDITED_DATA_NEG_SUPP 0x0040
|
||||
|
||||
/* CCITT compatibility levels */
|
||||
#define CCITT_1980_COMPATIBILITY 1980 /* 1980 compatibility */
|
||||
#define CCITT_1984_COMPATIBILITY 1984 /* 1984 compatibility */
|
||||
#define CCITT_1988_COMPATIBILITY 1988 /* 1988 compatibility */
|
||||
|
||||
/* permitted minimum and maximum values for setting the X.25 configuration */
|
||||
#define MIN_PACKET_WINDOW 1 /* the minimum packet window size */
|
||||
#define MAX_PACKET_WINDOW 7 /* the maximum packet window size */
|
||||
#define MIN_DATA_PACKET_SIZE 16 /* the minimum Data packet size */
|
||||
#define MAX_DATA_PACKET_SIZE 4096 /* the maximum Data packet size */
|
||||
#define MIN_X25_ASYNC_TIMEOUT 1000 /* the minimum asynchronous packet timeout value */
|
||||
#define MAX_X25_ASYNC_TIMEOUT 60000 /* the maximum asynchronous packet timeout value */
|
||||
#define MIN_X25_ASYNC_RETRY_COUNT 0 /* the minimum asynchronous packet retry count */
|
||||
#define MAX_X25_ASYNC_RETRY_COUNT 250 /* the maximum asynchronous packet retry count */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define X25_MAX_DATA 1024 /* max length of X.25 data buffer */
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
unsigned char qdm; /* Q/D/M bits */
|
||||
unsigned char cause; /* cause field */
|
||||
unsigned char diagn; /* diagnostics */
|
||||
unsigned char pktType;
|
||||
unsigned short length;
|
||||
unsigned char result;
|
||||
unsigned short lcn;
|
||||
unsigned short mtu;
|
||||
unsigned short mru;
|
||||
char reserved[3];
|
||||
}x25api_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
x25api_hdr_t hdr;
|
||||
char data[X25_MAX_DATA];
|
||||
}x25api_t;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Return codes from interface commands
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
#define NO_X25_EXCEP_COND_TO_REPORT 0x51 /* there is no X.25 exception condition to report */
|
||||
#define X25_COMMS_DISABLED 0x51 /* X.25 communications are not currently enabled */
|
||||
#define X25_COMMS_ENABLED 0x51 /* X.25 communications are currently enabled */
|
||||
#define DISABLE_X25_COMMS_BEFORE_CFG 0x51 /* X.25 communications must be disabled before setting the configuration */
|
||||
#define X25_CFG_BEFORE_COMMS_ENABLED 0x52 /* perform a SET_X25_CONFIGURATION before enabling X.25 comms */
|
||||
#define LGTH_X25_CFG_DATA_INVALID 0x52 /* the length of the passed X.25 configuration data is invalid */
|
||||
#define LGTH_X25_INT_DATA_INVALID 0x52 /* the length of the passed interrupt trigger data is invalid */
|
||||
#define LINK_LEVEL_NOT_CONNECTED 0x52 /* the HDLC link is not currently in the ABM */
|
||||
#define INVALID_X25_CFG_DATA 0x53 /* the passed X.25 configuration data is invalid */
|
||||
#define INVALID_X25_APP_IRQ_SELECTED 0x53 /* in invalid IRQ was selected in the SET_X25_INTERRUPT_TRIGGERS */
|
||||
#define X25_IRQ_TMR_VALUE_INVALID 0x54 /* an invalid application IRQ timer value was selected */
|
||||
#define INVALID_X25_PACKET_SIZE 0x55 /* the X.25 packet size is invalid */
|
||||
#define INVALID_X25_LCN_CONFIG 0x56 /* the X.25 logical channel configuration is invalid */
|
||||
#define SET_HDLC_CFG_BEFORE_X25_CFG 0x58 /* the HDLC configuration must be set before the X.25 configuration */
|
||||
#define HDLC_CFG_INVALID_FOR_X25 0x59 /* the HDLC configuration is invalid for X.25 usage */
|
||||
#define INVALID_LCN_SELECTION 0x60 /* the LCN selected is invalid */
|
||||
#define NO_LCN_AVAILABLE_CALL_REQ 0x60 /* no LCN is available for an outgoing Call Request */
|
||||
#define LCN_NOT_IN_DATA_XFER_ST 0x61 /* the LCN is not in the data transfer mode */
|
||||
#define NO_INCOMING_CALL_PENDING 0x61 /* no Call Request/Indication has been received */
|
||||
#define NO_CLEAR_REQ_PKT_RECEIVED 0x61 /* no Clear Request/Indication has been received */
|
||||
#define NO_RESET_REQ_PKT_RECEIVED 0x61 /* no Reset Request/Indication has been received */
|
||||
#define NO_RESTART_REQ_PKT_RECEIVED 0x61 /* no Restart Request/Indication has been received */
|
||||
#define NO_INTERRUPT_PKT_RECEIVED 0x61 /* no Interrupt packet has been received */
|
||||
#define NO_REGSTR_REQ_PKT_RECEIVED 0x61 /* no Registration Request has been received */
|
||||
#define LCN_STATE_INVALID_CLEAR_REQ 0x61 /* the LCN state is invalid for a Clear Request to be issued */
|
||||
#define LCN_STATE_INVALID_RESET_REQ 0x61 /* the LCN state is invalid for a Reset Request to be issued */
|
||||
#define LCN_STATE_INVALID_INTERRUPT 0x61 /* the LCN state is invalid for an Interrupt packet to be issued */
|
||||
#define ASYNC_BFR_IN_USE 0x62 /* the storage buffer used for asynchronous packet formatting is */
|
||||
/* currently in use */
|
||||
#define DEFINED_WINDOW_SIZE_INVALID 0x62 /* SET_PVC_CONFIGURATION - the selected window size is invalid */
|
||||
#define DEFINED_PACKET_SIZE_INVALID 0x63 /* SET_PVC_CONFIGURATION - the selected packet size is invalid */
|
||||
#define DATA_TRANSMIT_WINDOW_CLOSED 0x63 /* the transmit packet window is closed */
|
||||
#define NO_X25_DATA_PKT_AVAIL 0x63 /* no Data packet is available for reception by the */
|
||||
/* application on the selected LCN */
|
||||
#define INVALID_X25_PACKET_TYPE 0x63 /* the X25 packet type is invalid */
|
||||
#define INVALID_CALL_CONTROL_DEFN 0x63 /* INCOMING_CALL_CONTROL - the call control definition is invalid */
|
||||
#define D_BIT_ACK_OUTSTANDING 0x63 /* a response to a transmitted D-bit Data packet has not yet been */
|
||||
/* received */
|
||||
#define PREV_DATA_RX_NOT_COMPLETE 0x64 /* the application has not completed the previous RECEIVE_X25_DATA_PACKET command */
|
||||
#define PREV_DATA_TX_NOT_COMPLETE 0x64 /* the application has not completed the previous SEND_X25_DATA_PACKET command */
|
||||
#define INVALID_X25_PKT_LGTH 0x64 /* the length of the outgoing packet is invalid */
|
||||
#define CALL_ARGS_LGTH_EXCESSIVE 0x65 /* the outgoing call arguments are of excessive length */
|
||||
#define NO_CALLAC_FAST_SEL_RESTR_RESP 0x66 /* an incoming call received with Fast Select */
|
||||
/* facilities with restriction on response may not be accepted */
|
||||
#define REG_PRAGMATICS_NOT_SUPP 0x67 /* Registration pragmatics are not supported */
|
||||
#define PKT_NOT_PERMITTED_AT_DTE 0x68 /* the asynchronous packet may not be transmitted */
|
||||
/* at a station configured as a DTE */
|
||||
#define PKT_NOT_PERMITTED_AT_DCE 0x68 /* the asynchronous packet may not be transmitted */
|
||||
/* at a station configured as a DCE */
|
||||
#define USR_DATA_NOT_ALWD_ASYNC_PKT 0x69 /* a user data field is not permitted in the asynchronous packet */
|
||||
#define D_BIT_NOT_ALWD_CALL_SETUP_PKT 0x6A /* the D-bit may not be set in the asynchronous packet */
|
||||
#define FACIL_NOT_ALWD_OUTGOING_PKT 0x6B /* a facilities field is not permitted in the asynchronous packet */
|
||||
#define NO_CALL_DESTINATION_ADDR 0x6C /* - no '-d' definition found in the passed arguments */
|
||||
#define INVALID_ARGS_IN_ASYNC_PKT 0x6D /* there are invalid arguments included in the asynchronous packet */
|
||||
#define USER_DATA_FIELD_LGTH_ODD 0x6E /* the length of the passed user data is odd */
|
||||
#define ASYNC_PKT_RECEIVED 0x70 /* an asynchronous packet has been received */
|
||||
#define PROTOCOL_VIOLATION 0x71 /* a protocol violation has occurred */
|
||||
#define X25_TIMEOUT 0x72 /* an X.25 timeout has occured */
|
||||
#define ASYNC_PKT_RETRY_LIMIT_EXCEEDED 0x73 /* an X.25 asynchronous packet retry limit has been exceeded */
|
||||
#define INVALID_X25_COMMAND 0x7F /* the defined X25 interface command is invalid */
|
||||
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
|
||||
struct lapb_x25_register_struct {
|
||||
|
||||
unsigned long init;
|
||||
void (*x25_lapb_connect_indication)(void *x25_id,int reason);
|
||||
int (*x25_setparms)(struct net_device *dev, struct x25_parms_struct *conf);
|
||||
void (*x25_lapb_bh_kick)(void *x25_id);
|
||||
int (*x25_receive_pkt)(void *x25_id, struct sk_buff *skb);
|
||||
|
||||
int (*x25_register)(void **x25_lnk, struct net_device *lapb_dev, char *dev_name, struct net_device **new_dev);
|
||||
int (*x25_unregister_link)(void *x25_id);
|
||||
int (*x25_unregister)(struct net_device *x25_dev);
|
||||
|
||||
void (*x25_lapb_disconnect_confirm)(void *x25_id,int reason);
|
||||
void (*x25_lapb_disconnect_indication)(void *x25_id,int reason);
|
||||
void (*x25_lapb_connect_confirm)(void *x25_id,int reason);
|
||||
int (*x25_get_map)(void*, struct seq_file *);
|
||||
void (*x25_get_active_inactive)(void*,wp_stack_stats_t*);
|
||||
};
|
||||
|
||||
struct x25_dsp_register_struct {
|
||||
unsigned char init;
|
||||
int (*dsp_register)(struct net_device* x25_dev, char* dev_name, struct net_device **new_dev);
|
||||
int (*dsp_unregister)(struct net_device** x25_dev, void* dsp_id);
|
||||
int (*dsp_setparms)(void* dsp_id, void*);
|
||||
|
||||
int (*dsp_call_request)(void* dsp_id, void* sk_id, struct sk_buff* skb);
|
||||
int (*dsp_call_accept)(void* dsp_id, struct sk_buff* skb);
|
||||
void (*dsp_svc_up)(void* dsp_id);
|
||||
void (*dsp_svc_down)(void* dsp_id);
|
||||
void (*dsp_svc_ready)(void* dsp_id);
|
||||
void (*dsp_svc_reset)(void* dsp_id);
|
||||
|
||||
int (*dsp_receive_pkt)(void* dsp_id, struct sk_buff *skb);
|
||||
void (*dsp_x25_bh_kick)(void *dsp_id);
|
||||
int (*dsp_rx_buf_check)(void *dsp_id, int len);
|
||||
int (*dsp_oob_msg)(void *dsp_id, struct sk_buff* skb);
|
||||
int (*dsp_check_dev)(void *dsp_id);
|
||||
void (*dsp_get_active_inactive)(void*dsp_id,wp_stack_stats_t *);
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct wanpipe_x25_register_struct{
|
||||
|
||||
unsigned char init;
|
||||
|
||||
int (*x25_bind_api_to_svc)(struct net_device *master_dev, void *sk_id);
|
||||
int (*x25_bind_listen_to_link)(struct net_device *master_dev, void *sk_id, unsigned short protocol);
|
||||
int (*x25_unbind_listen_from_link)(void *sk_id,unsigned short protocol);
|
||||
|
||||
int (*x25_dsp_register)(struct net_device *x25_dev,
|
||||
char *dev_name,
|
||||
struct net_device **new_dev);
|
||||
|
||||
int (*x25_dsp_unregister)(void* dsp_id);
|
||||
int (*x25_dsp_setparms) (struct net_device *x25_dev,
|
||||
void* dsp_id,
|
||||
void *dsp_parms);
|
||||
|
||||
|
||||
};
|
||||
|
||||
extern int register_wanpipe_x25_protocol (struct wanpipe_x25_register_struct *x25_api_reg);
|
||||
extern void unregister_wanpipe_x25_protocol (void);
|
||||
|
||||
extern int x25_dsp_register(struct net_device *x25_dev,
|
||||
char *dev_name,
|
||||
struct net_device **new_dev);
|
||||
|
||||
extern int x25_dsp_unregister(void* dsp_id);
|
||||
extern int x25_dsp_setparms (struct net_device *x25_dev,
|
||||
void* dsp_id,
|
||||
void *dsp_parms);
|
||||
|
||||
extern void lapb_kickstart_tx (struct net_device *dev);
|
||||
|
||||
extern void lapb_set_mtu (struct net_device *dev, unsigned int mtu);
|
||||
|
||||
extern void lapb_link_unregister (struct net_device *dev);
|
||||
|
||||
extern void x25_dsp_id_unregister(struct net_device *dev);
|
||||
|
||||
extern int x25_dsp_is_svc_ready(struct net_device *dev);
|
||||
|
||||
extern void wan_skb_destructor (struct sk_buff *skb);
|
||||
#define CALL_LOG(x25_link,format,msg...) { if (x25_link && x25_link->cfg.call_logging){ \
|
||||
DEBUG_EVENT(format,##msg); \
|
||||
}else if(!x25_link){\
|
||||
DEBUG_EVENT(format,##msg); \
|
||||
}}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
APIINC = ../../include
|
||||
VPATH = $(SYSINC)
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../ -I../../lib -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: server_v1 \
|
||||
server_v2 \
|
||||
svc_client \
|
||||
pvc_client
|
||||
@echo "Ok."
|
||||
|
||||
|
||||
server_v1: server_v1.c ../../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
server_v2: server_v2.c ../../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
svc_client: svc_client.c ../../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
pvc_client: pvc_client.c ../../lib/lib_api.c
|
||||
|
||||
clean:
|
||||
rm -f server_v1
|
||||
rm -f server_v2
|
||||
rm -f svc_client
|
||||
rm -f pvc_client
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
X25 Annexg API Sample Code
|
||||
==========================
|
||||
|
||||
|
||||
Author: Nenad Corbic
|
||||
Date: Mar 25, 2003
|
||||
|
||||
The x25 annexg api package contains the sample client and server
|
||||
programs which should be used in application development.
|
||||
|
||||
|
||||
Contents of the API Package
|
||||
---------------------------
|
||||
|
||||
server_v1.c : Multi-Process server application that waits for incoming calls.
|
||||
Once a call is accepted, it spawns a child process to
|
||||
handle svc connection.
|
||||
|
||||
./server_v1 -i <lapb interface name> -r -w -txsize 100
|
||||
|
||||
server_v2.c : Single process server application that waits for incoming calls.
|
||||
Once a call is accepted, it start tx/rx data. All svc handing
|
||||
is done inside a single process.
|
||||
|
||||
./server_v2 -i <lapb interface name> -r -w -txsize 100
|
||||
|
||||
svc_client.c : Client application that places calls. Application
|
||||
doesn't wait for a call to be established; thus, multiple
|
||||
calls can be placed from a single process.
|
||||
|
||||
./svc_client -i <lapb interface name> -r -w -txsize 100 \
|
||||
-txcnt 100 \
|
||||
-txchan 1
|
||||
|
||||
|
|
@ -0,0 +1,815 @@
|
|||
/*****************************************************************************
|
||||
* server_v1.c X25 API: SVC Server Application
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 1995-2003 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 aserver utility will accept incoming x25 calls and start
|
||||
* receiving data on each channel.
|
||||
*
|
||||
* The aserver utility is process based, where the listen parent
|
||||
* will spawn child processes to handle each estabished connection.
|
||||
*
|
||||
* This utility should be used as an architectual model. It is up to
|
||||
* the user to handle all conditions of x25. Please refer to the
|
||||
* X25API programming manual for futher details.
|
||||
*/
|
||||
|
||||
/*===========================================================
|
||||
* Header Files: Includes
|
||||
*==========================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/wanpipe_x25_kernel.h>
|
||||
#include "lib_api.h"
|
||||
|
||||
/*===========================================================
|
||||
* Defines
|
||||
*==========================================================*/
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define DATA_SZ 5000
|
||||
|
||||
#define MAX_X25_ADDR_SIZE 16
|
||||
#define MAX_X25_DATA_SIZE 129
|
||||
#define MAX_X25_FACL_SIZE 110
|
||||
#define TIMEOUT 10
|
||||
|
||||
#define APP_NAME "server_v1"
|
||||
/*===========================================================
|
||||
* Global Variables
|
||||
*==========================================================*/
|
||||
|
||||
unsigned char Tx_data[DATA_SZ];
|
||||
unsigned char Rx_data[DATA_SZ];
|
||||
unsigned char prognamed[100];
|
||||
|
||||
|
||||
/* Defined global so it would only get allocated once.
|
||||
* If it was defined in MakeConnection() function it
|
||||
* would be allocated and dealocated every time we
|
||||
* run that function.
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char qdm;
|
||||
* unsigned char cause;
|
||||
* unsigned char diagn;
|
||||
* unsigned char pktType;
|
||||
* unsigned short length;
|
||||
* unsigned char result;
|
||||
* unsigned short lcn;
|
||||
* unsigned short mtu;
|
||||
* unsigned short mru;
|
||||
* char reserved[3];
|
||||
* }x25api_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* x25api_hdr_t hdr;
|
||||
* char data[X25_MAX_DATA];
|
||||
* }x25api_t;
|
||||
*
|
||||
*/
|
||||
|
||||
x25api_t api_cmd;
|
||||
|
||||
|
||||
/*============================================================
|
||||
Function Prototypes
|
||||
*===========================================================*/
|
||||
|
||||
int MakeConnection( char * );
|
||||
void tx_rx_data(int sock, int mtu, int mru);
|
||||
void sig_chld (int sigio);
|
||||
int issue_clear_call(int sock, int opt, int cause, int diagn);
|
||||
int handle_oob_event(int sock);
|
||||
int decode_oob_event(x25api_t* api_hdr, int sock);
|
||||
|
||||
void sig_hdlr (int sigio)
|
||||
{
|
||||
|
||||
printf("GOT USER SIG\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call send_socket() to transmit data
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
|
||||
card_cnt=1;
|
||||
|
||||
if (!init_args(argc,argv)){
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
signal(SIGUSR1,sig_hdlr);
|
||||
|
||||
proceed = MakeConnection(if_name);
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* o Start listening on a socket for incoming
|
||||
* calls.
|
||||
* o Accept an incoming call and spawn a child
|
||||
* to handle the connection.
|
||||
*/
|
||||
|
||||
int MakeConnection (char *i_name )
|
||||
{
|
||||
int err = 0;
|
||||
int sock=0, sock1=0;
|
||||
struct wan_sockaddr_ll sa;
|
||||
fd_set readset,oobset;
|
||||
int mtu=128,mru=128;
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
|
||||
sprintf(prognamed,"%s",APP_NAME);
|
||||
|
||||
/* Create a new socket */
|
||||
sock = socket( AF_WANPIPE, SOCK_RAW, AF_ANNEXG_WANPIPE);
|
||||
if( sock < 0 ) {
|
||||
perror("Socket");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Fill in binding information
|
||||
* before we use connect() system call
|
||||
* a socket must be binded into a virtual
|
||||
* network interface svc_connect.
|
||||
*
|
||||
* Card name must be supplied as well. In
|
||||
* this case the user supplies the name
|
||||
* eg: wanpipe1.
|
||||
*/
|
||||
sa.sll_family = AF_ANNEXG_WANPIPE;
|
||||
sa.sll_protocol = htons(ETH_P_X25);
|
||||
strcpy(sa.sll_device, "svc_listen");
|
||||
strcpy(sa.sll_card, i_name);
|
||||
|
||||
/* Bind a sock using the above address structure */
|
||||
if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) == -1){
|
||||
perror("Bind");
|
||||
printf("%s: Failed to bind socket to %s interface\n",
|
||||
prognamed,i_name);
|
||||
close(sock);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (listen(sock,10) != 0){
|
||||
perror("Listen");
|
||||
close(sock);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
printf("%s: Server waiting form incoming calls ...\n",
|
||||
prognamed);
|
||||
|
||||
for (;;){
|
||||
|
||||
/* Accept call will block and wait for incoming calls.
|
||||
* When a call comes in, a new socket will be created
|
||||
* sock1. NOTE: that connection is not established yet.*/
|
||||
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_SET(sock,&readset);
|
||||
FD_SET(sock,&oobset);
|
||||
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
if (select(sock+1,&readset,NULL,&oobset,NULL)){
|
||||
|
||||
if (FD_ISSET(sock,&oobset)){
|
||||
printf("%s: Listen sock rx OOB event!\n",
|
||||
prognamed);
|
||||
close(sock);
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock,&readset)){
|
||||
|
||||
printf("\n");
|
||||
|
||||
sock1 = accept(sock,NULL,NULL);
|
||||
|
||||
if (sock1 < 0){
|
||||
perror("Socket");
|
||||
printf ("%s: Sock Accept Call FAILED BAD,no sock %i\n",
|
||||
prognamed,sock1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((err=ioctl(sock1,SIOC_X25_GET_CALL_DATA,&api_cmd)) != 0){
|
||||
perror("Get Call Data");
|
||||
printf("%s: Failed to Get Call data %i\n",
|
||||
prognamed,err);
|
||||
close(sock1);
|
||||
break;
|
||||
}
|
||||
|
||||
api_cmd.data[api_cmd.hdr.length]=0;
|
||||
printf("%s: Rx Call Data Lcn %i String %s, MTU %i MRU %i\n",
|
||||
prognamed,
|
||||
api_cmd.hdr.lcn,api_cmd.data,
|
||||
api_cmd.hdr.mtu, api_cmd.hdr.mru);
|
||||
|
||||
mtu=api_cmd.hdr.mtu;
|
||||
mru=api_cmd.hdr.mru;
|
||||
|
||||
if ((err=ioctl(sock1,SIOC_X25_ACCEPT_CALL,0)) != 0){
|
||||
perror("Accept Call");
|
||||
printf("%s: Accept failed %i\n",
|
||||
prognamed,err);
|
||||
close(sock1);
|
||||
break;
|
||||
}
|
||||
|
||||
printf("%s: Rx Call Accept Sock=%i Lcn=%i\n\n",
|
||||
prognamed,
|
||||
sock1,
|
||||
api_cmd.hdr.lcn);
|
||||
|
||||
|
||||
if (!fork()){
|
||||
close(sock);
|
||||
tx_rx_data(sock1,mtu,mru);
|
||||
exit(0);
|
||||
}
|
||||
close(sock1);
|
||||
sock1=0;
|
||||
}
|
||||
}
|
||||
|
||||
/* We must check if our children have died or not
|
||||
* otherwise our process table will be full of
|
||||
* zombie children */
|
||||
|
||||
/* Instead of having children send a SIGCHILD signal
|
||||
* to the server indicating their death, we poll
|
||||
* every time a new child is created. This is not
|
||||
* perfect but it works :) */
|
||||
|
||||
sig_chld(0);
|
||||
}
|
||||
|
||||
sig_chld(0);
|
||||
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*=================================================================
|
||||
* TX_RX_DATA
|
||||
*
|
||||
* o Send and Receive data via socket
|
||||
* o Create a tx packet using x25api_t data type.
|
||||
* o Both the tx and rx packets contains 16 bytes headers
|
||||
* in front of the real data. It is the responsibility
|
||||
* of the applicatino to insert this 16 bytes on tx, and
|
||||
* remove the 16 bytes on rx.
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* o 16 byte Header: data structure:
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char qdm PACKED; Q/D/M bits
|
||||
* unsigned char cause PACKED; cause field
|
||||
* unsigned char diagn PACKED; diagnostics
|
||||
* unsigned char pktType PACKED;
|
||||
* unsigned short length PACKED;
|
||||
* unsigned char result PACKED;
|
||||
* unsigned short lcn PACKED;
|
||||
* char reserved[7] PACKED;
|
||||
* }x25api_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* x25api_hdr_t hdr PACKED;
|
||||
* char data[X25_MAX_DATA] PACKED;
|
||||
* }x25api_t;
|
||||
*
|
||||
* TX DATA:
|
||||
* --------
|
||||
* Each tx data packet must contain the above 16 byte header!
|
||||
*
|
||||
* Only relevant byte in the 16 byte tx header, is the
|
||||
* QDM byte. The driver will look at this byte to determine
|
||||
* if the Mbit (more data bit) should be set.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* RX DATA:
|
||||
* --------
|
||||
* Each rx data will contain the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte rx header, are the
|
||||
* LCN and QDM bytes.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* LCN = contains the lcn number for the rx frame.
|
||||
*
|
||||
* OOB DATA:
|
||||
* ---------
|
||||
* The OOB (out of band) data is used by the driver to
|
||||
* indicate x25 events for the active channel:
|
||||
* clear call, or restarts.
|
||||
*
|
||||
* Each OOB packet contains the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte oob header, are the
|
||||
* pktType, cause and diagn bytes.
|
||||
*
|
||||
* pktType = event type (ex Clear Call, Restart ...)
|
||||
* cause = x25 cause of the event
|
||||
* diagn = x25 diagnostic information used to determine
|
||||
* the cause of the event.
|
||||
*
|
||||
* Upon receiving an event, the sock should be considered
|
||||
* DEAD!!! Meaning it must be closed using the close()
|
||||
* function.
|
||||
*/
|
||||
|
||||
void tx_rx_data(int sock, int mtu, int mru)
|
||||
{
|
||||
unsigned int Tx_count=0;
|
||||
unsigned short timeout=0;
|
||||
int err=0, i, Rx_count=0;
|
||||
struct timeval tv;
|
||||
x25api_t* api_tx_el;
|
||||
fd_set writeset,readset,oobset;
|
||||
int volatile send_ok=0;
|
||||
pid_t pid = getpid();
|
||||
|
||||
sprintf(prognamed,"\t%s[%i]",APP_NAME,pid);
|
||||
|
||||
/* If user leaves the tx_cnt as default 1
|
||||
* we assume that user wants the server
|
||||
* to send infinitely. Thus, only stop if
|
||||
* the user explicity sets the tx_cnt to
|
||||
* a non default value */
|
||||
if (tx_cnt==1){
|
||||
tx_cnt=0;
|
||||
}
|
||||
|
||||
/* Specify timeout value to 5 seconds on select */
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 5;
|
||||
|
||||
api_tx_el = (x25api_t *)Tx_data;
|
||||
|
||||
if (tx_size > mtu){
|
||||
printf("%s: Tx Size %i greater than MTU %i, using MTU!\n",
|
||||
prognamed,
|
||||
tx_size,
|
||||
mtu);
|
||||
tx_size=mtu;
|
||||
}
|
||||
|
||||
/* Fill in the packet data */
|
||||
for (i=0; i<tx_size ; i++){
|
||||
api_tx_el->data[i] = (unsigned char) i;
|
||||
}
|
||||
|
||||
/* Set the pid information used by the wanpipe
|
||||
* proc file system: /proc/net/wanrouter/map
|
||||
* (Optional) */
|
||||
|
||||
if ((err=ioctl(sock,SIOC_X25_SET_LCN_PID,&pid))){
|
||||
perror("Set LCN PID: ");
|
||||
printf("%s: Failed to set pid info\n",prognamed);
|
||||
close(sock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the label information used by the wanpipe
|
||||
* proc file system: /proc/net/wanrouter/map
|
||||
* (Optional) */
|
||||
|
||||
sprintf(prognamed,"%s",APP_NAME);
|
||||
if ((err=ioctl(sock,SIOC_X25_SET_LCN_LABEL,prognamed))){
|
||||
perror("Label: ");
|
||||
printf("%s: Failed to configure svc label\n",prognamed);
|
||||
close(sock);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(prognamed,"\t%s[%i]",APP_NAME,pid);
|
||||
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_ZERO(&writeset);
|
||||
|
||||
FD_SET(sock,&readset);
|
||||
FD_SET(sock,&oobset);
|
||||
|
||||
if (write_enable && send_ok){
|
||||
FD_SET(sock,&writeset);
|
||||
}
|
||||
|
||||
/* This must be within the loop */
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = TIMEOUT;
|
||||
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if already queued packet
|
||||
* cannot be sent
|
||||
*/
|
||||
|
||||
if((err=select(sock + 1, &readset, &writeset, &oobset, &tv))){
|
||||
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&readset)){
|
||||
|
||||
err = recv(sock, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
perror("Recv");
|
||||
|
||||
printf("%s: Failed to rcv %i , %i\n",
|
||||
prognamed,Rx_count, err);
|
||||
|
||||
if (ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0)){
|
||||
printf("%s: Sock Disconnected !\n",
|
||||
prognamed);
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
|
||||
/* Every received packet comes with the 16
|
||||
* bytes of header which driver adds on.
|
||||
* Header is structured as x25api_hdr_t.
|
||||
* (same as above)
|
||||
*/
|
||||
x25api_hdr_t *api_data =
|
||||
(x25api_hdr_t *)Rx_data;
|
||||
|
||||
++Rx_count;
|
||||
|
||||
err-=sizeof(x25api_hdr_t);
|
||||
if (err > mru){
|
||||
/* This should never happen, sanity check */
|
||||
printf("%s: Rx warning: rx len %i > mru %i\n",
|
||||
prognamed,
|
||||
err,mru);
|
||||
}
|
||||
|
||||
if (api_data->qdm & M_BIT){
|
||||
/* This packet is part of a larger
|
||||
* packet. Concatinate it... */
|
||||
}
|
||||
|
||||
if (verbose){
|
||||
printf("%s:\tReceive OK, size: %i, qdm %x, lcn %i cnt: %i\n",
|
||||
prognamed,
|
||||
err, api_data->qdm,
|
||||
api_data->lcn,
|
||||
Rx_count);
|
||||
}
|
||||
send_ok=1;
|
||||
|
||||
//pause();
|
||||
//if ((Rx_count%50)==0){
|
||||
// printf("Sleeping on Rx_count = %i\n",Rx_count);
|
||||
// sleep(5);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock,&oobset)){
|
||||
if (handle_oob_event(sock) == 0){
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&writeset)){
|
||||
|
||||
err = send(sock, Tx_data,
|
||||
tx_size + sizeof(x25api_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0) {
|
||||
if (errno != EBUSY){
|
||||
perror("Send");
|
||||
printf("%s: Failed to send %i , %i\n",
|
||||
prognamed,
|
||||
Tx_count, err);
|
||||
|
||||
if (ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0)){
|
||||
printf("%s: Sock Disconnected !\n",
|
||||
prognamed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
++Tx_count;
|
||||
|
||||
if (verbose){
|
||||
printf("%s: Packet Sent %i\n",prognamed,Tx_count);
|
||||
}
|
||||
send_ok=0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Stop after number of frames if the
|
||||
* tx_cnt is defined */
|
||||
|
||||
if(tx_cnt && Tx_count >= tx_cnt){
|
||||
issue_clear_call(sock,CLEAR_WAIT_FOR_DATA,cause,diagn);
|
||||
break;
|
||||
}
|
||||
|
||||
timeout=0;
|
||||
}else{
|
||||
if (err == 0){
|
||||
if (++timeout == 5){
|
||||
printf("%s: Sock timeout exceeded MAXIMUM\n",prognamed);
|
||||
break;
|
||||
}
|
||||
printf("%s: Sock timeout try again !!!\n",prognamed);
|
||||
}else{
|
||||
printf("%s: Error in Select !!!\n",prognamed);
|
||||
break;
|
||||
}
|
||||
}//if select
|
||||
}//for
|
||||
close(sock);
|
||||
printf("%s: Connection %i closed: Tx=%i Rx=%i\n",
|
||||
prognamed,sock,Tx_count,Rx_count);
|
||||
}
|
||||
|
||||
|
||||
void sig_chld (int sigio)
|
||||
{
|
||||
pid_t pid;
|
||||
int stat;
|
||||
|
||||
while ((pid=waitpid(-1,&stat,WNOHANG)) > 0){
|
||||
//printf("%s: Child %d terminated\n",prognamed,pid);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int handle_oob_event(int sock)
|
||||
{
|
||||
int err;
|
||||
x25api_t* api_tx_el;
|
||||
|
||||
/* The OOB Message will indicate that an
|
||||
* asynchronous event occured. The applicaton
|
||||
* must stop everything and check the state of
|
||||
* the link. Since link might
|
||||
* have gone down */
|
||||
|
||||
/* In this example I just exit. A real
|
||||
* application would check the state of the
|
||||
* sock first by reading the header information.
|
||||
*/
|
||||
|
||||
/* IMPORTANT:
|
||||
* If we fail to read the OOB message, we can
|
||||
* assume that the link is down. Thus, close
|
||||
* the socket and continue !!! */
|
||||
|
||||
err = recv(sock, Rx_data, sizeof(Rx_data), MSG_OOB);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err < 0){
|
||||
|
||||
/* The state of the socket is disconnected.
|
||||
* We must close the socket and continue with
|
||||
* operatio */
|
||||
|
||||
if ((err=ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0)) == 0){
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%s: SockId=%i : OOB Event : State = %s\n",
|
||||
prognamed,sock,
|
||||
err == 1 ? "Disconnected" : "(Dis/Con)necting");
|
||||
|
||||
memset(&api_cmd,0,sizeof(api_cmd));
|
||||
if ((err=ioctl(sock,SIOC_X25_GET_CALL_DATA,&api_cmd)) == 0){
|
||||
if (decode_oob_event(&api_cmd,sock) == 0){
|
||||
close(sock);
|
||||
sock=0;
|
||||
}
|
||||
}else{
|
||||
close(sock);
|
||||
sock=0;
|
||||
}
|
||||
|
||||
/* Do what ever you have to do to handle
|
||||
* this condiditon */
|
||||
}else{
|
||||
|
||||
/* OOB packet received OK ! */
|
||||
|
||||
api_tx_el = (x25api_t *)Rx_data;
|
||||
|
||||
#if 0
|
||||
printf("%s: SockId=%i : OOB : Packet type 0x%02X, Cause 0x%02X,"
|
||||
" Diagn 0x%02X, Result 0x%02X, Len %i, LCN %i\n",
|
||||
prognamed,
|
||||
sock,
|
||||
api_tx_el->hdr.pktType,
|
||||
api_tx_el->hdr.cause,
|
||||
api_tx_el->hdr.diagn,
|
||||
api_tx_el->hdr.result,
|
||||
api_tx_el->hdr.length,
|
||||
api_tx_el->hdr.lcn);
|
||||
#endif
|
||||
|
||||
if (decode_oob_event(api_tx_el,sock) == 0){
|
||||
close(sock);
|
||||
sock=0;
|
||||
}else{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int decode_oob_event(x25api_t* api_hdr, int sock)
|
||||
{
|
||||
|
||||
switch (api_hdr->hdr.pktType){
|
||||
|
||||
case RESET_REQUEST_PKT:
|
||||
printf("%s: SockId=%i : OOB : Rx Reset Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
prognamed,
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
/* NOTE: we don't have to close the socket,
|
||||
* since the reset doesn't clear the call
|
||||
* however, it means that there is something really
|
||||
* wrong and that data has been lost */
|
||||
return 1;
|
||||
|
||||
|
||||
case CLEAR_REQUEST_PKT:
|
||||
printf("%s: SockId=%i : OOB : Rx Clear Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
prognamed,
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
|
||||
case RESTART_REQUEST_PKT:
|
||||
printf("%s: SockId=%i : OOB : Rx Restart Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
prognamed,
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
case INTERRUPT_PKT:
|
||||
printf("%s: SockId=%i : OOB : Rx Interrupt Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
prognamed,
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("%s: SockId=%i : OOB : Rx Type=0x%02X : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
prognamed,
|
||||
sock,
|
||||
api_hdr->hdr.pktType,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* issue_clear_call
|
||||
*
|
||||
* Input options (opt):
|
||||
* CLEAR_WAIT_FOR_DATA : Fail the clear call if data is
|
||||
* still pending the transmisstion.
|
||||
* This way tx data is not lost
|
||||
* due to the clear call.
|
||||
* CLEAR_NO_WAIT: Clear call regardless of current
|
||||
* pending data.
|
||||
*
|
||||
* NOTE: This function can block, which can cause buffer
|
||||
* overrun on other lcn's. Thus, it should be executed
|
||||
* in a separate process.
|
||||
*/
|
||||
|
||||
int issue_clear_call(int sock, int opt, int cause, int diagn)
|
||||
{
|
||||
|
||||
memset(&api_cmd,0,sizeof(x25api_t));
|
||||
|
||||
api_cmd.hdr.cause=cause;
|
||||
api_cmd.hdr.diagn=diagn;
|
||||
|
||||
if (verbose){
|
||||
printf("%s: Issuing Clear Call: SockId=%i Cause=%d Diagn=%d\n\n",
|
||||
prognamed, sock,cause,diagn);
|
||||
}
|
||||
|
||||
if (opt){
|
||||
while(ioctl(sock,SIOC_WANPIPE_CHECK_TX,NULL));
|
||||
}
|
||||
|
||||
if (ioctl(sock,SIOC_X25_CLEAR_CALL,&api_cmd)){
|
||||
perror("Clear Call: ");
|
||||
}
|
||||
|
||||
printf("%s: SockId=%i: Call Cleared !\n",
|
||||
prognamed,
|
||||
sock);
|
||||
|
||||
close(sock);
|
||||
sock=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,981 @@
|
|||
/*****************************************************************************
|
||||
* svc_client.c X25 API: SVC Client Application
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 1995-2003 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 svc_utility utility will establish, user defined number, of
|
||||
* outgoing calls and tx/rx, user defined number, of packets on each
|
||||
* active svc.
|
||||
*
|
||||
* This utility should be used as an architectual model. It is up to
|
||||
* the user to handle all conditions of x25. Please refer to the
|
||||
* X25API programming manual for futher details.
|
||||
*/
|
||||
|
||||
/*===========================================================
|
||||
* Header Files: Includes
|
||||
*==========================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <wait.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/wanpipe_x25_kernel.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include "lib_api.h"
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* Defines
|
||||
*==========================================================*/
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
|
||||
#define TX_PACKET_LEN 5000
|
||||
#define MAX_RX_PKT_LEN 5000
|
||||
|
||||
#define MAX_X25_ADDR_SIZE 16
|
||||
#define MAX_X25_DATA_SIZE 129
|
||||
#define MAX_X25_FACL_SIZE 110
|
||||
|
||||
#define MAX_SOCK_NUM 255
|
||||
|
||||
#define TIMEOUT 10
|
||||
|
||||
#define NOWAIT_ON_CONNECT 1
|
||||
|
||||
#define APP_NAME "svc_client"
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* Global Variables
|
||||
*==========================================================*/
|
||||
|
||||
|
||||
/* A single packet will be used to simulate tx data */
|
||||
unsigned char Tx_data[TX_PACKET_LEN];
|
||||
|
||||
/* A singel Rx buffer will be used to accept incoming
|
||||
* data. The buffer will be overwritten with each new
|
||||
* packet. */
|
||||
unsigned char Rx_data[MAX_RX_PKT_LEN];
|
||||
|
||||
|
||||
/* For each socket created, we will keep the
|
||||
* socket file descriptor and tx/rx pkt counts */
|
||||
typedef struct sock_api {
|
||||
int sock;
|
||||
int tx;
|
||||
int rx;
|
||||
int mtu;
|
||||
int mru;
|
||||
}sock_api_t;
|
||||
|
||||
sock_api_t sock_fd[MAX_SOCK_NUM];
|
||||
|
||||
int max_sock_fd=0;
|
||||
|
||||
/* X25 tx/rx header structure. This structure will
|
||||
* be used to send commands down to the driver, as
|
||||
* well as read/insert header information from/into
|
||||
* rx and tx data respectively.
|
||||
*
|
||||
* Defined globaly so it would only get allocated once.
|
||||
*/
|
||||
|
||||
x25api_t api_cmd;
|
||||
|
||||
unsigned char prognamed[100];
|
||||
|
||||
|
||||
/*============================================================
|
||||
Function Prototypes
|
||||
*===========================================================*/
|
||||
int MakeConnection( char * );
|
||||
void tx_rx_data( void);
|
||||
void setup_signal_handlers (void);
|
||||
void quit (int);
|
||||
int decode_oob_event(x25api_t* api_hdr, int sk_index);
|
||||
int issue_clear_call(int i, int opt, int cause, int diagn);
|
||||
void sig_chld (int sigio);
|
||||
void sig_hnd (int sigio);
|
||||
int rx_data_act(int i);
|
||||
int tx_data_act(int i,int Tx_lgth);
|
||||
int handle_oob_event(int sk_index);
|
||||
void close_connection(int i);
|
||||
|
||||
|
||||
|
||||
/*=============================================================
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call tx_rx_data() to transmit/receive data
|
||||
*
|
||||
*============================================================*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
pid_t pid;
|
||||
int stat;
|
||||
int i;
|
||||
|
||||
sprintf(prognamed,"%s[%i]",APP_NAME,getpid());
|
||||
|
||||
card_cnt=1;
|
||||
if (init_args(argc,argv) == 0){
|
||||
usage(argv[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
signal(SIGCHLD,&sig_chld);
|
||||
signal(SIGINT,&sig_hnd);
|
||||
signal(SIGTERM,&sig_hnd);
|
||||
|
||||
memset(sock_fd,0,sizeof(sock_fd));
|
||||
|
||||
printf("\n%s: Attempting to establish %i calls, and tx %i (%i bytes) packets \n",
|
||||
prognamed, tx_channels, tx_cnt, tx_size);
|
||||
|
||||
proceed = MakeConnection(if_name);
|
||||
if (proceed == TRUE){
|
||||
|
||||
tx_rx_data();
|
||||
|
||||
/* Wait for the clear call children */
|
||||
while ((pid=waitpid(-1,&stat,WUNTRACED)) > 0){
|
||||
//printf("Child %d terminated\n",pid);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0;i<tx_channels;i++){
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* MakeConnection
|
||||
*
|
||||
* For user defined number of connections
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* o Setup x25 place call information
|
||||
* o Place call using connect()
|
||||
* o Read out the lcn used for that connection
|
||||
*==========================================================*/
|
||||
|
||||
int MakeConnection (char *i_name )
|
||||
{
|
||||
int len = sizeof(struct wan_sockaddr_ll);
|
||||
int err = 0;
|
||||
struct wan_sockaddr_ll sa;
|
||||
int i;
|
||||
int calls_issued=0;
|
||||
pid_t pid;
|
||||
|
||||
|
||||
for (i=0; i<tx_channels; i++){
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
|
||||
/* Create a new socket */
|
||||
sock_fd[i].sock = socket( AF_WANPIPE, SOCK_RAW, AF_WANPIPE);
|
||||
if( sock_fd[i].sock < 0 ) {
|
||||
perror("Socket: ");
|
||||
sock_fd[i].sock=0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Fill in binding information
|
||||
* before we use connect() system call
|
||||
* a socket must be binded into a virtual
|
||||
* network interface svc_connect.
|
||||
*
|
||||
* Card name must be supplied as well. In
|
||||
* this case the user supplies the name
|
||||
* eg: wanpipe1.
|
||||
*/
|
||||
sa.sll_family = AF_WANPIPE;
|
||||
sa.sll_protocol = htons(ETH_P_X25);
|
||||
strcpy(sa.sll_device, "svc_connect");
|
||||
strcpy(sa.sll_card, i_name);
|
||||
|
||||
|
||||
/* Bind a sock using the above address structure */
|
||||
if(bind(sock_fd[i].sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) == -1){
|
||||
perror("Bind: ");
|
||||
printf("Failed to bind socket to %s interface\n",i_name);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* Reset the api command structure */
|
||||
memset(&api_cmd, 0, sizeof(x25api_t));
|
||||
|
||||
/* Write the call data into the command structure.
|
||||
* Note: -u data must be have even number of characters.
|
||||
* -f field cannot be set to zero (i.e. -f0)
|
||||
* Refer to x25.pdf hardware manual.
|
||||
*/
|
||||
sprintf(api_cmd.data,"-d%s -s%s -u%s",
|
||||
daddr,
|
||||
saddr,
|
||||
udata);
|
||||
api_cmd.hdr.length = strlen(api_cmd.data);
|
||||
|
||||
/* Write the call data into a socket mail box using
|
||||
* the following ioctl call. This must be one before
|
||||
* the connect system call
|
||||
*/
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_X25_SET_CALL_DATA,&api_cmd)) != 0){
|
||||
perror("Set Call Data: ");
|
||||
printf ("%s: Setting call data Failed 0x%X!\n",
|
||||
prognamed,SIOC_X25_SET_CALL_DATA);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Set the pid information used by the wanpipe
|
||||
* proc file system: /proc/net/wanrouter/map
|
||||
* (Optional) */
|
||||
|
||||
pid=getpid();
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_X25_SET_LCN_PID,&pid))){
|
||||
perror("Set LCN PID: ");
|
||||
printf("Failed to sending down my pid %i\n",pid);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Set the label information used by the wanpipe
|
||||
* proc file system: /proc/net/wanrouter/map
|
||||
* (Optional) */
|
||||
sprintf(prognamed,"%s",APP_NAME);
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_X25_SET_LCN_LABEL,prognamed))){
|
||||
perror("Label: ");
|
||||
printf("%s: Failed to configure label\n",prognamed);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
continue;
|
||||
}
|
||||
|
||||
sprintf(prognamed,"%s[%i]",APP_NAME,getpid());
|
||||
|
||||
|
||||
/* Now we are ready to place a call. The address
|
||||
* structure is optional. The sa structure will contain
|
||||
* a network interface name on which the connection was
|
||||
* established
|
||||
*/
|
||||
if (connect(sock_fd[i].sock, (struct sockaddr *)&sa, len) != 0){
|
||||
perror("Connect: ");
|
||||
printf("%s: Failed to place call !\n",prognamed);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* In order to see what lcn we have established connection on,
|
||||
* run GET CALL DATA ioctl call, which will return the
|
||||
* appropriate information into api_cmd structure
|
||||
*/
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_X25_GET_CALL_DATA,&api_cmd)) != 0){
|
||||
perror("Get Call Data: ");
|
||||
printf("%s: Failed to obtain call data!\n",prognamed);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Determine the negotiated values such as lcn number
|
||||
* mtu and mru */
|
||||
sock_fd[i].mtu=api_cmd.hdr.mtu;
|
||||
sock_fd[i].mru=api_cmd.hdr.mru;
|
||||
|
||||
printf("%s: Call Bounded to LCN=%i MTU=%i MRU=%i \n",
|
||||
prognamed,
|
||||
api_cmd.hdr.lcn,
|
||||
api_cmd.hdr.mtu,
|
||||
api_cmd.hdr.mru);
|
||||
|
||||
calls_issued++;
|
||||
|
||||
if (sock_fd[i].sock > max_sock_fd){
|
||||
max_sock_fd=sock_fd[i].sock;
|
||||
}
|
||||
|
||||
/* Flush all pending print statements to screen */
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* At this point all the calls has been placed. If the connect() function
|
||||
* has been used in blocking mode, then we will wait in select() for
|
||||
* the accept calls to come in. Otherwise, the calls have been accepted,
|
||||
* and can proceed to tx and rx data. */
|
||||
|
||||
printf("%s: Issued %i Calls, Requested %i\n\n\n",
|
||||
prognamed,calls_issued,tx_channels);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*=================================================================
|
||||
* TX_RX_DATA
|
||||
*
|
||||
* o Send and Receive data via socket
|
||||
* o Create a tx packet using x25api_t data type.
|
||||
* o Both the tx and rx packets contains 16 bytes headers
|
||||
* in front of the real data. It is the responsibility
|
||||
* of the applicatino to insert this 16 bytes on tx, and
|
||||
* remove the 16 bytes on rx.
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* o 16 byte Header: data structure:
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char qdm PACKED; Q/D/M bits
|
||||
* unsigned char cause PACKED; cause field
|
||||
* unsigned char diagn PACKED; diagnostics
|
||||
* unsigned char pktType PACKED;
|
||||
* unsigned short length PACKED;
|
||||
* unsigned char result PACKED;
|
||||
* unsigned short lcn PACKED;
|
||||
* char reserved[7] PACKED;
|
||||
* }x25api_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* x25api_hdr_t hdr PACKED;
|
||||
* char data[X25_MAX_DATA] PACKED;
|
||||
* }x25api_t;
|
||||
*
|
||||
* TX DATA:
|
||||
* --------
|
||||
* Each tx data packet must contain the above 16 byte header!
|
||||
*
|
||||
* Only relevant byte in the 16 byte tx header, is the
|
||||
* QDM byte. The driver will look at this byte to determine
|
||||
* if the Mbit (more data bit) should be set.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* RX DATA:
|
||||
* --------
|
||||
* Each rx data will contain the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte rx header, are the
|
||||
* LCN and QDM bytes.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* LCN = contains the lcn number for the rx frame.
|
||||
*
|
||||
* OOB DATA:
|
||||
* ---------
|
||||
* The OOB (out of band) data is used by the driver to
|
||||
* indicate x25 events for the active channel:
|
||||
* clear call, or restarts.
|
||||
*
|
||||
* Each OOB packet contains the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte oob header, are the
|
||||
* pktType, cause and diagn bytes.
|
||||
*
|
||||
* pktType = event type (ex Clear Call, Restart ...)
|
||||
* cause = x25 cause of the event
|
||||
* diagn = x25 diagnostic information used to determine
|
||||
* the cause of the event.
|
||||
*
|
||||
* Upon receiving an event, the sock should be considered
|
||||
* DEAD!!! Meaning it must be closed using the close()
|
||||
* function.
|
||||
*/
|
||||
|
||||
void tx_rx_data(void)
|
||||
{
|
||||
unsigned short timeout=0;
|
||||
int err=0, i;
|
||||
struct timeval tv;
|
||||
x25api_t* api_tx_el;
|
||||
fd_set writeset,readset,oobset;
|
||||
|
||||
/* Setup a timeout value for the select statement, which is
|
||||
* going to block until the socket(s) are/is ready to tx/rx
|
||||
* or oob. In this case we will timeout afte 10 seconds of
|
||||
* inactivity */
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
|
||||
|
||||
/* Cast the x25 16 byte header to the begining
|
||||
* of the tx packet. Using the pointer fill
|
||||
* in appropriate header information such as
|
||||
* QDM bits */
|
||||
api_tx_el = (x25api_t *)Tx_data;
|
||||
|
||||
/* Initialize the 16 byte header */
|
||||
memset(api_tx_el, 0, sizeof(x25api_hdr_t));
|
||||
|
||||
/* Set the Mbit (more bit)
|
||||
* currently this option is disabled */
|
||||
#ifdef MORE_BIT_SET
|
||||
api_tx_el->hdr.qdm = 0x01
|
||||
#endif
|
||||
|
||||
/* Fill in the tx packet data with arbitrary
|
||||
* information */
|
||||
for (i=0; i<tx_size ; i++){
|
||||
api_tx_el->data[i] = (unsigned char) i;
|
||||
}
|
||||
|
||||
|
||||
/* Start an infinite loop which will tx/rx data
|
||||
* over connected x25 svc's */
|
||||
|
||||
for(;;) {
|
||||
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
|
||||
/* Initialize select() flags */
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_ZERO(&writeset);
|
||||
|
||||
/* For all connected sockets, tell the select
|
||||
* what to wait for. Tx, Rx and OOB */
|
||||
for (i=0;i<tx_channels;i++){
|
||||
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
FD_SET(sock_fd[i].sock,&readset);
|
||||
FD_SET(sock_fd[i].sock,&oobset);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock_fd[i].sock,&writeset);
|
||||
}
|
||||
}
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active x25 sockets.
|
||||
*
|
||||
* If the NONBLOCKING option has been used during connect()
|
||||
* the select will wait untill the channel is connected
|
||||
* (i.e. accept has been received). Once the channel is connected
|
||||
* the tx and rx will start. However, if the call is cleared for
|
||||
* any reason, the OOB message will indicate that event.
|
||||
*/
|
||||
|
||||
if((err=select(max_sock_fd + 1,&readset, &writeset, &oobset, &tv))){
|
||||
|
||||
/* One of the sockets returned OK for tx rx or oob
|
||||
* Thus, for all waiting connections, check each flag */
|
||||
|
||||
for (i=0;i<tx_channels;i++){
|
||||
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
/* First check for OOB messages */
|
||||
if (FD_ISSET(sock_fd[i].sock,&oobset)){
|
||||
if (handle_oob_event(i)){
|
||||
close_connection(i);
|
||||
}
|
||||
goto svc_action;
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock_fd[i].sock,&readset)){
|
||||
if (rx_data_act(i)){
|
||||
close_connection(i);
|
||||
goto svc_action;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock_fd[i].sock,&writeset)){
|
||||
|
||||
tx_data_act(i,tx_size);
|
||||
|
||||
/* In this example I am clearing the connection
|
||||
* after I sent user specified number of packets */
|
||||
if (tx_delay)
|
||||
sleep(tx_delay);
|
||||
|
||||
|
||||
//if (sock_fd[i].tx == 10){
|
||||
// ioctl(sock_fd[i].sock,SIOC_X25_RESET_CALL,0);
|
||||
//}
|
||||
|
||||
if (sock_fd[i].tx >= tx_cnt){
|
||||
|
||||
issue_clear_call(i, CLEAR_WAIT_FOR_DATA, cause, diagn);
|
||||
close_connection(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
svc_action:
|
||||
/* All channels are down ! */
|
||||
if (!max_sock_fd){
|
||||
break;
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
/* select timeout occured. The svc could be
|
||||
* waiting for the accept, or there is something wrong
|
||||
* with the x25 configuration.
|
||||
*
|
||||
* It is up to the user to handle this condition
|
||||
* as they see fit */
|
||||
|
||||
if (err == 0){
|
||||
if (++timeout == 5){
|
||||
printf("Select() timeout exceeded MAXIMUM\n");
|
||||
break;
|
||||
}
|
||||
printf("Select() timeout try again !!!\n");
|
||||
}else{
|
||||
printf("Error in Select() !!!\n");
|
||||
break;
|
||||
}
|
||||
}//if select
|
||||
}//for
|
||||
|
||||
for (i=0;i<tx_channels;i++){
|
||||
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int tx_data_act(int i, int Tx_lgth)
|
||||
{
|
||||
int err;
|
||||
x25api_t* api_tx_el = (x25api_t *)Tx_data;
|
||||
|
||||
|
||||
/* This socket is ready to tx */
|
||||
#if 0
|
||||
if (Tx_lgth > sock_fd[i].mtu){
|
||||
printf("%s: Tx warning: Tx length %i > MTU %i, using MTU!\n",
|
||||
prognamed,Tx_lgth,sock_fd[i].mtu);
|
||||
Tx_lgth=sock_fd[i].mtu;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The tx packet length contains the 16 byte
|
||||
* header. The tx packet was created above. */
|
||||
err = send(sock_fd[i].sock, Tx_data,
|
||||
Tx_lgth + sizeof(x25api_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err>0){
|
||||
++sock_fd[i].tx;
|
||||
if (verbose){
|
||||
printf("%s: SockId=%i : TX : size=%i, qdm=0x%02X, cnt=%i\n",
|
||||
prognamed,
|
||||
sock_fd[i].sock,
|
||||
Tx_lgth,
|
||||
api_tx_el->hdr.qdm,
|
||||
sock_fd[i].tx);
|
||||
}
|
||||
}else{
|
||||
if (errno != EBUSY){
|
||||
perror("Send");
|
||||
}
|
||||
}
|
||||
|
||||
/* If err<=0 it means that the send failed and that
|
||||
* driver is busy. Thus, the packet should be
|
||||
* requeued for re-transmission on the next
|
||||
* try !!!!
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int rx_data_act(int i)
|
||||
{
|
||||
|
||||
int err;
|
||||
|
||||
/* This socket has received a packet. */
|
||||
|
||||
err = recv(sock_fd[i].sock, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
|
||||
perror("Recv");
|
||||
|
||||
/* This should never happen. However, check the sock state:
|
||||
* if we are still connected, proceed with normal operation.
|
||||
*/
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_SOCK_STATE,0)) == X25_OK){
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("%s: Sockid=%i : Failed to rcv packet %i\n",
|
||||
prognamed,
|
||||
sock_fd[i].sock,
|
||||
err);
|
||||
return 1;
|
||||
|
||||
}else{
|
||||
|
||||
/* Packet received OK !
|
||||
*
|
||||
* Every received packet comes with the 16
|
||||
* bytes of header which driver adds on.
|
||||
* Header is structured as x25api_hdr_t.
|
||||
* (same as above)
|
||||
*/
|
||||
|
||||
x25api_hdr_t *api_data =
|
||||
(x25api_hdr_t *)Rx_data;
|
||||
|
||||
if (!read_enable){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
err-=sizeof(x25api_hdr_t);
|
||||
|
||||
if (err > sock_fd[i].mru){
|
||||
/* This should never happen, sanity check */
|
||||
printf("%s: Rx warning: Rx len %i > MRU %i\n",
|
||||
prognamed,
|
||||
err,sock_fd[i].mru);
|
||||
}
|
||||
|
||||
if (api_data->qdm & 0x01){
|
||||
|
||||
/* More bit is set, thus
|
||||
* handle it accordingly
|
||||
* FIXME */
|
||||
}
|
||||
|
||||
++sock_fd[i].rx;
|
||||
|
||||
if (verbose){
|
||||
printf("%s: SockId=%i : RX : size=%i, qdm=0x%02X, cnt=%i\n",
|
||||
prognamed,
|
||||
sock_fd[i].sock,
|
||||
err,
|
||||
api_data->qdm,
|
||||
sock_fd[i].rx);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_oob_event(int i)
|
||||
{
|
||||
int err;
|
||||
x25api_t* api_tx_el;
|
||||
|
||||
/* The OOB Message will indicate that an
|
||||
* asynchronous event occured. The applicaton
|
||||
* must stop everything and check the state of
|
||||
* the link. Since link might
|
||||
* have gone down */
|
||||
|
||||
/* In this example I just exit. A real
|
||||
* application would check the state of the
|
||||
* sock first by reading the header information.
|
||||
*/
|
||||
|
||||
/* IMPORTANT:
|
||||
* If we fail to read the OOB message, we can
|
||||
* assume that the link is down. Thus, close
|
||||
* the socket and continue !!! */
|
||||
|
||||
err = recv(sock_fd[i].sock, Rx_data, sizeof(Rx_data), MSG_OOB);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err < 0){
|
||||
|
||||
/* The state of the socket is disconnected.
|
||||
* We must close the socket and continue with
|
||||
* operatio */
|
||||
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_SOCK_STATE,0)) == X25_OK){
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("%s: SockId=%i : OOB Event : State = %s\n",
|
||||
prognamed,sock_fd[i].sock,
|
||||
err == 1 ? "Disconnected" : "(Dis/Con)necting");
|
||||
|
||||
memset(&api_cmd,0,sizeof(api_cmd));
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_X25_GET_CALL_DATA,&api_cmd)) == 0){
|
||||
if (decode_oob_event(&api_cmd, i) == 0){
|
||||
return 1;
|
||||
}
|
||||
}else{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Do what ever you have to do to handle
|
||||
* this condiditon */
|
||||
}else{
|
||||
|
||||
/* OOB packet received OK ! */
|
||||
|
||||
api_tx_el = (x25api_t *)Rx_data;
|
||||
|
||||
#if 0
|
||||
printf("%s: SockId=%i : OOB : Packet type 0x%02X, Cause 0x%02X,"
|
||||
" Diagn 0x%02X, Result 0x%02X, Len %i, LCN %i\n",
|
||||
prognamed,
|
||||
sock_fd[i].sock,
|
||||
api_tx_el->hdr.pktType,
|
||||
api_tx_el->hdr.cause,
|
||||
api_tx_el->hdr.diagn,
|
||||
api_tx_el->hdr.result,
|
||||
api_tx_el->hdr.length,
|
||||
api_tx_el->hdr.lcn);
|
||||
#endif
|
||||
if (decode_oob_event(api_tx_el, i) == 0){
|
||||
return 0;
|
||||
}else{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int decode_oob_event(x25api_t* api_hdr, int sk_index)
|
||||
{
|
||||
|
||||
switch (api_hdr->hdr.pktType){
|
||||
|
||||
case RESET_REQUEST_PKT:
|
||||
printf("%s: SockId=%i : OOB : Rx Reset Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
prognamed,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
/* NOTE: we don't have to close the socket,
|
||||
* since the reset doesn't clear the call
|
||||
* however, it means that there is something really
|
||||
* wrong and that data has been lost */
|
||||
return 1;
|
||||
|
||||
|
||||
case CLEAR_REQUEST_PKT:
|
||||
printf("%s: SockId=%i : OOB : Rx Clear Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
prognamed,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
|
||||
case RESTART_REQUEST_PKT:
|
||||
printf("%s: SockId=%i : OOB : Rx Restart Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
prognamed,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
case INTERRUPT_PKT:
|
||||
printf("%s: SockId=%i : OOB : Rx Interrupt Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
prognamed,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("%s: SockId=%i : OOB : Rx Type=0x%02X : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
prognamed,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.pktType,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* issue_clear_call
|
||||
*
|
||||
* Input options (opt):
|
||||
* CLEAR_WAIT_FOR_DATA : Fail the clear call if data is
|
||||
* still pending the transmisstion.
|
||||
* This way tx data is not lost
|
||||
* due to the clear call.
|
||||
* CLEAR_NO_WAIT: Clear call regardless of current
|
||||
* pending data.
|
||||
*
|
||||
* NOTE: This function can block, which can cause buffer
|
||||
* overrun on other lcn's. Thus, it should be executed
|
||||
* in a separate process.
|
||||
*/
|
||||
|
||||
int issue_clear_call(int i, int opt, int cause, int diag)
|
||||
{
|
||||
//FIXME: Fork is expensive use Pthread
|
||||
if (fork() == 0){
|
||||
|
||||
sprintf(prognamed,"%s[%i]",APP_NAME,getpid());
|
||||
|
||||
if (opt){
|
||||
int cnt=0;
|
||||
while(ioctl(sock_fd[i].sock,SIOC_WANPIPE_CHECK_TX,NULL)){
|
||||
++cnt;
|
||||
}
|
||||
//printf("%s: Wait Count %i\n",prognamed,cnt);
|
||||
}
|
||||
|
||||
memset(&api_cmd,0,sizeof(x25api_t));
|
||||
api_cmd.hdr.cause=cause;
|
||||
api_cmd.hdr.diagn=diag;
|
||||
|
||||
printf("\n%s: Issuing Clear Call: SockId=%i, Cause=%d Diagn=%d\n\n",
|
||||
prognamed, sock_fd[i].sock, cause, diag);
|
||||
|
||||
if (ioctl(sock_fd[i].sock,SIOC_X25_CLEAR_CALL,&api_cmd)){
|
||||
perror("Clear Call: ");
|
||||
}
|
||||
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
exit(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sig_chld (int sigio)
|
||||
{
|
||||
pid_t pid;
|
||||
int stat;
|
||||
|
||||
while ((pid=waitpid(-1,&stat,WNOHANG)) > 0){
|
||||
//printf("Child %d terminated\n",pid);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void sig_hnd (int sigio)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<tx_channels;i++){
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
void new_max_sock_fd(void)
|
||||
{
|
||||
int i;
|
||||
max_sock_fd=0;
|
||||
for (i=0;i<tx_channels;i++){
|
||||
if (sock_fd[i].sock > max_sock_fd){
|
||||
max_sock_fd=sock_fd[i].sock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void close_connection(int i)
|
||||
{
|
||||
close(sock_fd[i].sock);
|
||||
|
||||
printf("%s: Connection SockId=%i closed: Tx=%i Rx=%i\n",
|
||||
prognamed,
|
||||
sock_fd[i].sock,
|
||||
sock_fd[i].tx,
|
||||
sock_fd[i].rx);
|
||||
|
||||
if (max_sock_fd == sock_fd[i].sock){
|
||||
sock_fd[i].sock=0;
|
||||
new_max_sock_fd();
|
||||
//printf("%s: Finding new max sock %i\n",prognamed,max_sock_fd);
|
||||
}
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
VPATH = $(SYSINC)
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: pos_api
|
||||
@echo "Ok."
|
||||
|
||||
#bsc_cmd: bsc_cmd.c
|
||||
# $(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
pos_api: pos_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
|
||||
clean:
|
||||
rm -f pos_api
|
|
@ -0,0 +1,630 @@
|
|||
/*****************************************************************************
|
||||
* pos_api.c POS API
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 2003 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 pos_api.c utility interfaces to the POS kernel driver
|
||||
* via socket ioctl() calls.
|
||||
*
|
||||
* Please refer to the POS API document that conatins
|
||||
* detailed information on all POS commands.
|
||||
*
|
||||
* Please use the program as a building block for your POS
|
||||
* application.
|
||||
*
|
||||
* This example has been written for a single interface in mind,
|
||||
* where the same process handles tx and rx data.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/* General Linux header files */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
/* Wanpipe header files */
|
||||
#include <linux/wanrouter.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_pos.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Defines
|
||||
*==================================================*/
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define LGTH_CRC_BYTES 2
|
||||
#define MAX_TX_DATA 50 /* Size of tx data */
|
||||
#define MAX_FRAMES 5000 /* Number of frames to transmit */
|
||||
|
||||
#define POS_UDELAY 100000 /* 100ms */
|
||||
|
||||
#define POS_PORT_ENABLE 0
|
||||
#define POS_PORT_DISABLE -1
|
||||
|
||||
#define is_port_ready(x) ((x>0)?1:0)
|
||||
|
||||
#define POS_ASYNC_PORT1 1
|
||||
#define POS_ASYNC_PORT2 2
|
||||
|
||||
#define POS_PORT1 1
|
||||
#define POS_PORT2 2
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Golobal data
|
||||
*==================================================*/
|
||||
|
||||
unsigned short Rx_lgth;
|
||||
unsigned char Rx_data[4000];
|
||||
unsigned char Tx_data[MAX_TX_DATA + sizeof(wan_api_hdr_t)];
|
||||
int sock;
|
||||
|
||||
/* Structure used to execute POS commands
|
||||
*
|
||||
* struct {
|
||||
* unsigned char wan_pos_opp_flag
|
||||
* unsigned char wan_pos_pos_state
|
||||
* unsigned char wan_pos_async_state
|
||||
* unsigned char wan_pos_command
|
||||
* unsigned short wan_pos_data_len
|
||||
* unsigned char wan_pos_return_code
|
||||
* unsigned char wan_pos_port_num
|
||||
* unsigned char wan_pos_attr
|
||||
* unsigned char wan_pos_data[1030]
|
||||
* }wan_mbox_t
|
||||
*
|
||||
* NOTE: This is the representation of the wan_mbox_t
|
||||
* structure. Note how its actually defined.
|
||||
* It should be used for information purposes
|
||||
* only. i.e. DO NOT TRY TO USE THIS STRUCTURE
|
||||
* DEFINITION IN THE ACTUAL CODE :)
|
||||
*/
|
||||
static wan_mbox_t mbox_g;
|
||||
|
||||
|
||||
/*===================================================
|
||||
* Function Prototypes
|
||||
*==================================================*/
|
||||
int MakeConnection(wan_mbox_t *, char *, char *);
|
||||
void process_con(wan_mbox_t *);
|
||||
int pos_data_ready(int sock, wan_mbox_t *mbox,
|
||||
short *rx_port1, short *rx_port2,
|
||||
short *rx_async_port1, short *tx_async_port1,
|
||||
short *rx_async_port2, short *tx_async_port2,
|
||||
unsigned int udelay);
|
||||
|
||||
|
||||
/*===================================================
|
||||
* DoCommand
|
||||
*
|
||||
* Execute a POS command directly on the
|
||||
* sangoma adapter.
|
||||
*
|
||||
*/
|
||||
|
||||
int DoCommand (wan_mbox_t *mbox)
|
||||
{
|
||||
return ioctl(sock, SIOC_WANPIPE_EXEC_CMD, mbox);
|
||||
}
|
||||
|
||||
/*===================================================
|
||||
* configure_pos
|
||||
*
|
||||
* Setup a POS configuration structure and
|
||||
* execute a POS CONFIGURATION command.
|
||||
*
|
||||
* IMPORTANT:
|
||||
* The current configuration is only a
|
||||
* SAMPLE. It should be changed to sute
|
||||
* your network.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
int configure_pos (wan_mbox_t *mbox)
|
||||
{
|
||||
CONFIGURATION_STRUCT cfg;
|
||||
|
||||
mbox->wan_pos_command=CONFIGURE;
|
||||
mbox->wan_pos_port_num=0;
|
||||
|
||||
memset(&cfg, 0, sizeof(CONFIGURATION_STRUCT));
|
||||
|
||||
/* number of active SDLC lines */
|
||||
cfg.sdlc_lines=0x02;
|
||||
|
||||
|
||||
/* maximum tx data packet */
|
||||
cfg.sdlc_maxdata = DFT_POSDATA;
|
||||
|
||||
/* number of active ASYNC lines */
|
||||
cfg.async_lines=0x02;
|
||||
|
||||
/* asynchronous line(s) speed */
|
||||
cfg.async_speed=0x03; /* 19200 bps*/
|
||||
|
||||
/* half/full-duplex configuration
|
||||
* 1=Full Duplex
|
||||
* 0=Half Duplex */
|
||||
cfg.half_duplex = 1;
|
||||
|
||||
memcpy(mbox->wan_pos_data,&cfg,sizeof(CONFIGURATION_STRUCT));
|
||||
mbox->wan_pos_data_len=sizeof(CONFIGURATION_STRUCT);
|
||||
|
||||
if (DoCommand(mbox) != 0){
|
||||
printf("Failed to configure pos!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
printf("Pos Configured\n");
|
||||
|
||||
|
||||
/* Enable POS Port 1 */
|
||||
memset(mbox,0, 0x16);
|
||||
|
||||
mbox->wan_pos_command=ENABLE_POS;
|
||||
mbox->wan_pos_data_len=0;
|
||||
mbox->wan_pos_port_num=1;
|
||||
|
||||
if (DoCommand(mbox) != 0){
|
||||
printf("Failed to enable port 1!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
memset(mbox,0, 0x16);
|
||||
|
||||
/* Enable POS Port 2 */
|
||||
mbox->wan_pos_command=ENABLE_POS;
|
||||
mbox->wan_pos_data_len=0;
|
||||
mbox->wan_pos_port_num=2;
|
||||
|
||||
if (DoCommand(mbox) != 0){
|
||||
printf("Failed to enable port 2!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
printf("Enabled Port 1 and 2\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*===================================================
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*
|
||||
* The "sock" socket descriptor will be use by
|
||||
* the rest of the program to execute ioctl()
|
||||
* commands down to the kernel driver.
|
||||
*==================================================*/
|
||||
|
||||
int MakeConnection(wan_mbox_t *mbox, char *r_name, char *i_name )
|
||||
{
|
||||
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", r_name, i_name);
|
||||
|
||||
strcpy( sa.sll_device, i_name);
|
||||
strcpy( sa.sll_card, r_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",i_name);
|
||||
exit(0);
|
||||
}
|
||||
printf("Socket bound to %s\n\n",i_name);
|
||||
|
||||
memset(mbox,0, 0x16);
|
||||
|
||||
return configure_pos(mbox);
|
||||
}
|
||||
|
||||
/*===================================================
|
||||
* pos_receive_data
|
||||
*
|
||||
* Execute POS receive command for a
|
||||
* specific PORT.
|
||||
*
|
||||
* Copy the rx packet into the user supplied
|
||||
* Rx_data buffer if the rx command is
|
||||
* successful.
|
||||
*==================================================*/
|
||||
|
||||
int pos_receive_data(wan_mbox_t *mbox, char cmd, char port, unsigned char *Rx_data)
|
||||
{
|
||||
memset(mbox,0, 0x16);
|
||||
mbox->wan_pos_command = cmd;
|
||||
mbox->wan_pos_data_len = 0;
|
||||
mbox->wan_pos_port_num = port;
|
||||
|
||||
if (DoCommand(mbox) != 0){
|
||||
printf("Failed to receive on %s port %i: %s!\n",
|
||||
cmd==RECEIVE_POS?"POS":"Async",
|
||||
port,
|
||||
strerror(errno));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(Rx_data, mbox->wan_pos_data, mbox->wan_pos_data_len);
|
||||
|
||||
/* Debugging:
|
||||
* Prints out the received packet in HEX or ASCII */
|
||||
{
|
||||
int i;
|
||||
printf("DATA: ");
|
||||
for (i=0;i<mbox->wan_pos_data_len;i++){
|
||||
|
||||
//Print in HEX
|
||||
printf("0x%02X ",Rx_data[i]);
|
||||
|
||||
//Print in ASCII
|
||||
//printf("%c ",Rx_data[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
return mbox->wan_pos_data_len;
|
||||
}
|
||||
|
||||
/*===================================================
|
||||
* pos_send_data
|
||||
*
|
||||
* Execute POS send command for a
|
||||
* specific ASYNC TX PORT.
|
||||
*
|
||||
*==================================================*/
|
||||
int pos_send_data(wan_mbox_t *mbox, char port, unsigned char *Tx_data, int Tx_len)
|
||||
{
|
||||
memset(mbox,0, 0x16);
|
||||
|
||||
mbox->wan_pos_command = SEND_ASYNC;
|
||||
mbox->wan_pos_data_len = Tx_len;
|
||||
mbox->wan_pos_port_num = port;
|
||||
|
||||
memcpy(mbox->wan_pos_data,Tx_data,Tx_len);
|
||||
|
||||
if (DoCommand(mbox) != 0){
|
||||
printf("Failed to tx on Async port %i: %s!\n",
|
||||
port,
|
||||
strerror(errno));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return Tx_len;
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* process_con
|
||||
*
|
||||
* o Setup the tx and rx buffers
|
||||
*
|
||||
* o Poll the POS ports 1 and 2 and POS ASYNC ports 1 and 2
|
||||
* Note, that one must select which port the polling
|
||||
* routine should poll on.
|
||||
*
|
||||
* o Receive and Tx
|
||||
*
|
||||
*
|
||||
* IMPORTANT:
|
||||
* On TX if the send command fails, one must
|
||||
* retransmit the same buffer again.
|
||||
*/
|
||||
void process_con(wan_mbox_t *mbox)
|
||||
{
|
||||
unsigned int Rx_count,Tx_count,Tx_length;
|
||||
short rx_port1,rx_port2,
|
||||
rx_async_port1,tx_async_port1,
|
||||
rx_async_port2,tx_async_port2;
|
||||
int err,i;
|
||||
|
||||
Rx_count = 0;
|
||||
Tx_count = 0;
|
||||
Tx_length = MAX_TX_DATA;
|
||||
|
||||
memset(&Tx_data[0],0,MAX_TX_DATA);
|
||||
|
||||
|
||||
/* Create a data packet */
|
||||
for (i=0;i<Tx_length;i++){
|
||||
Tx_data[i] = (unsigned char)1;
|
||||
}
|
||||
|
||||
printf("Starting Pos Tx/Rx, POS_UDELAY=%i \n",POS_UDELAY);
|
||||
|
||||
for(;;) {
|
||||
|
||||
/* Indicate which on which ports we'd like to tx or
|
||||
* receive. Note port1 and port2 are receive only.
|
||||
*
|
||||
* The pos_data_ready() function will use these values
|
||||
* to determin what data the user is waiting for.
|
||||
*
|
||||
* POS_PORT_ENABLE: Indicates that we'd like to be
|
||||
* woken up when data is available.
|
||||
*
|
||||
* POS_PORT_DISABLE:Ignore data on this port
|
||||
*
|
||||
* In this case we would like to rx/tx data on
|
||||
* all available ports
|
||||
*/
|
||||
rx_port1=POS_PORT_ENABLE;
|
||||
rx_port2=POS_PORT_ENABLE;
|
||||
rx_async_port1=POS_PORT_ENABLE;
|
||||
tx_async_port1=POS_PORT_DISABLE;
|
||||
rx_async_port2=POS_PORT_ENABLE;
|
||||
tx_async_port2=POS_PORT_DISABLE;
|
||||
|
||||
|
||||
/* The pos_data_ready() function must be used to implement flow control.
|
||||
* It will block using the POS_UDELAY if no data is available, before
|
||||
* POS buffers are re-checked.
|
||||
*/
|
||||
|
||||
if(pos_data_ready(sock,mbox,
|
||||
&rx_port1,&rx_port2,
|
||||
&rx_async_port1,&tx_async_port1,
|
||||
&rx_async_port2,&tx_async_port2,
|
||||
POS_UDELAY) == 0){
|
||||
|
||||
/* Rx packets on PORT 1*/
|
||||
if (is_port_ready(rx_port1)){
|
||||
err = pos_receive_data(mbox,RECEIVE_POS, POS_PORT1,Rx_data);
|
||||
/* err indicates bytes received */
|
||||
if(err > 0) {
|
||||
printf("Received packet %i, Port %i Length = %i\n",
|
||||
++Rx_count,
|
||||
POS_PORT1,
|
||||
err);
|
||||
}
|
||||
}
|
||||
|
||||
/* Rx packets on PORT 2 */
|
||||
if (is_port_ready(rx_port2)){
|
||||
err = pos_receive_data(mbox,RECEIVE_POS, POS_PORT2,Rx_data);
|
||||
if (err > 0){
|
||||
|
||||
printf("Received packet %i, Port %i Length = %i\n",
|
||||
++Rx_count,
|
||||
POS_PORT2,
|
||||
err);
|
||||
}
|
||||
}
|
||||
|
||||
/* Rx packets on Async PORT 1 */
|
||||
if (is_port_ready(rx_async_port1)){
|
||||
err = pos_receive_data(mbox,RECEIVE_ASYNC, POS_ASYNC_PORT1,Rx_data);
|
||||
if(err > 0) {
|
||||
printf("Received packet %i, Async Port %i Length = %i\n",
|
||||
++Rx_count,
|
||||
POS_ASYNC_PORT1,
|
||||
err);
|
||||
}
|
||||
}
|
||||
|
||||
/* Tx packets on Async PORT 1 */
|
||||
if (is_port_ready(tx_async_port1)){
|
||||
|
||||
if (tx_async_port2 < Tx_length){
|
||||
printf("Tx failed on Async port not enough room %i<%i\n",
|
||||
tx_async_port2,Tx_length);
|
||||
}else{
|
||||
err = pos_send_data(mbox,POS_ASYNC_PORT1,Tx_data,Tx_length);
|
||||
if(err > 0) {
|
||||
printf("Tx packet %i, Async Port %i Length = %i\n",
|
||||
++Tx_count,
|
||||
Tx_length,
|
||||
POS_ASYNC_PORT1);
|
||||
}else{
|
||||
//printf("Tx failed on Async port %i\n",
|
||||
// POS_ASYNC_PORT1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Rx packets on Async PORT 2 */
|
||||
if (is_port_ready(rx_async_port2)){
|
||||
err = pos_receive_data(mbox,RECEIVE_ASYNC, POS_ASYNC_PORT2,Rx_data);
|
||||
if(err > 0) {
|
||||
printf("Received packet %i, Async Port %i Length = %i\n",
|
||||
++Rx_count,
|
||||
POS_ASYNC_PORT2,
|
||||
err);
|
||||
}
|
||||
}
|
||||
|
||||
/* Tx packets on Async PORT 2 */
|
||||
if (is_port_ready(tx_async_port2)){
|
||||
|
||||
if (tx_async_port2 < Tx_length){
|
||||
printf("Tx failed on Async port 2 not enough room %i<%i\n",
|
||||
tx_async_port2,Tx_length);
|
||||
}else{
|
||||
|
||||
err = pos_send_data(mbox,POS_ASYNC_PORT2,Tx_data,Tx_length);
|
||||
if(err > 0) {
|
||||
printf("Tx packet %i, Async Port %i Length = %i\n",
|
||||
++Tx_count,
|
||||
Tx_length,
|
||||
POS_ASYNC_PORT2);
|
||||
}else{
|
||||
//printf("Tx failed on Async port %i\n",
|
||||
// POS_ASYNC_PORT2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop the program afer transmitting MAX_FRAMES */
|
||||
if (Tx_count == MAX_FRAMES)
|
||||
break;
|
||||
|
||||
} else {
|
||||
printf("\nError selecting socket\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
close (sock);
|
||||
}
|
||||
|
||||
/*===========================================================
|
||||
* pos_data_ready
|
||||
*
|
||||
* Execute the POS STATUS command and check if
|
||||
* there is any data on each of the POS ports.
|
||||
*
|
||||
* We also check the user defined ports we
|
||||
* should be waiting on. The port must
|
||||
* be enabled and data must be found on that
|
||||
* port before we exit and indicate event.
|
||||
*/
|
||||
|
||||
|
||||
int pos_data_ready(int sock, wan_mbox_t *mbox,
|
||||
short *rx_port1, short *rx_port2,
|
||||
short *rx_async_port1, short *tx_async_port1,
|
||||
short *rx_async_port2, short *tx_async_port2,
|
||||
unsigned int udelay)
|
||||
{
|
||||
int err;
|
||||
struct timeval tv;
|
||||
POSSTATESTRUC *tmp_pos_state;
|
||||
|
||||
for (;;){
|
||||
memset(mbox,0, 0x16);
|
||||
|
||||
mbox->wan_pos_command = SEND_RECV_STATE;
|
||||
mbox->wan_pos_data_len = 0;
|
||||
|
||||
if ((err=DoCommand(mbox)) != 0){
|
||||
printf("Failed to get pos status info %x!\n",err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp_pos_state = (POSSTATESTRUC*)mbox->wan_pos_data;
|
||||
|
||||
if (*rx_port1==POS_PORT_ENABLE && tmp_pos_state->POS1_received){
|
||||
*rx_port1=tmp_pos_state->POS1_received;
|
||||
udelay=0;
|
||||
}
|
||||
|
||||
if (*rx_port2==POS_PORT_ENABLE && tmp_pos_state->POS2_received){
|
||||
*rx_port2=tmp_pos_state->POS2_received;
|
||||
udelay=0;
|
||||
}
|
||||
|
||||
if (*rx_async_port1==POS_PORT_ENABLE && tmp_pos_state->async1_recvd){
|
||||
*rx_async_port1=tmp_pos_state->async1_recvd;
|
||||
udelay=0;
|
||||
}
|
||||
|
||||
if (*tx_async_port1==POS_PORT_ENABLE && tmp_pos_state->async1_transm){
|
||||
*tx_async_port1=tmp_pos_state->async1_transm;
|
||||
udelay=0;
|
||||
}
|
||||
|
||||
if (*rx_async_port2==POS_PORT_ENABLE && tmp_pos_state->async2_recvd){
|
||||
*rx_async_port2=tmp_pos_state->async2_recvd;
|
||||
udelay=0;
|
||||
}
|
||||
|
||||
if (*tx_async_port2==POS_PORT_ENABLE && tmp_pos_state->async2_transm){
|
||||
*tx_async_port2=tmp_pos_state->async2_transm;
|
||||
udelay=0;
|
||||
}
|
||||
|
||||
/* Something has been found, or the user has put
|
||||
* in a ZERO delay which means that we shouldn't
|
||||
* block */
|
||||
if (!udelay){
|
||||
#if 0
|
||||
printf("POS State: PP1=%d, PP2=%d, APr1=%d, APt1=%d, APr2=%d, APt2=%d\n",
|
||||
tmp_pos_state->POS1_received,
|
||||
tmp_pos_state->POS2_received,
|
||||
tmp_pos_state->async1_recvd,
|
||||
tmp_pos_state->async1_transm,
|
||||
tmp_pos_state->async2_recvd,
|
||||
tmp_pos_state->async2_transm);
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Nothing found on any of the ports,
|
||||
* sleep for user defined time and
|
||||
* proceed with polling */
|
||||
tv.tv_usec = udelay;
|
||||
tv.tv_sec = 0;
|
||||
|
||||
select(sock+1, NULL,NULL,NULL,&tv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call process_con() to read/write the POS API
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
|
||||
if (argc != 3){
|
||||
printf("Usage: rec_wan_sock <router name> <interface name>\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
memset(&mbox_g,0,sizeof(wan_mbox_t));
|
||||
|
||||
proceed = MakeConnection(&mbox_g,argv[argc - 2], argv[argc - 1]);
|
||||
if( proceed == TRUE ){
|
||||
process_con(&mbox_g);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
Binary file not shown.
|
@ -0,0 +1,31 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
VPATH = $(SYSINC)
|
||||
APIINC = ./
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: sdlc_api
|
||||
@echo "Ok."
|
||||
|
||||
sdlc_api: sdlc_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
|
||||
clean:
|
||||
rm -f sdlc_api
|
|
@ -0,0 +1,53 @@
|
|||
BISYCN API Package
|
||||
==================
|
||||
|
||||
Author: Nenad Corbic
|
||||
Date: May 29, 2004
|
||||
|
||||
|
||||
|
||||
The sdlc package contains the sample sdlc client
|
||||
program that should be used in user application
|
||||
development.
|
||||
|
||||
|
||||
Contents of the API Package
|
||||
---------------------------
|
||||
|
||||
1) sdlc_api.c : A sample API utility, that will send and receive
|
||||
data packets across a sdlc line. This program
|
||||
should be used as a starting point in developing
|
||||
a real-world sdlc application.
|
||||
|
||||
|
||||
Development Note:
|
||||
|
||||
SDLC driver only supports single socket interface
|
||||
for multiple SDLC channels.
|
||||
|
||||
This complicates the TX part of the application.
|
||||
Application MUST enable its own Tx delay in order
|
||||
to throttle the tx data.
|
||||
|
||||
Since single socket is provided, for multiple
|
||||
SDLC channels, one can only have TWO processes,
|
||||
one for Tx and other for Rx paths.
|
||||
Thus, TX throttling problem cannot be solved by
|
||||
just using multiple processes.
|
||||
|
||||
The sdlc_api implements tx throttling :)
|
||||
|
||||
Note: wanpipe1.conf interface (eg: sdlc0) must
|
||||
be configured for API mode.
|
||||
|
||||
|
||||
|
||||
Usage: sdlc_api <router name> <interface name> <num of stations>
|
||||
|
||||
eg: sdlc_api wanpipe1 sdlc0 2
|
||||
|
||||
Tx/Rx data on Station Station 1 and 2
|
||||
|
||||
To enable Tx send a SIGUSR1 signal to sdlc_api
|
||||
kill -SIGUSR1 $(pidof sdlc_api) or run ./tx_test
|
||||
|
|
@ -0,0 +1,658 @@
|
|||
/*****************************************************************************
|
||||
* bsc_api.c BiSync API: Receive Module
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 bsc_api.c utility will bind to a socket to a bsc 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.
|
||||
*
|
||||
* Command Documentation:
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_sdlc.h>
|
||||
#include "sdlc_api.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define LGTH_CRC_BYTES 2
|
||||
#define MAX_TX_DATA 100 /* Size of tx data */
|
||||
#define MAX_FRAMES 5000 /* Number of frames to transmit */
|
||||
|
||||
#define STATION_ADDR 0x01
|
||||
#define MAX_SDLC_LIST 100
|
||||
|
||||
#define MAX_INIT_SDLC_ADDR_CFG 1
|
||||
|
||||
#define MAX_TX_DELAY 10000
|
||||
#define MAX_INIT_TX_CNT 0
|
||||
|
||||
/*===================================================
|
||||
* Golobal data
|
||||
*==================================================*/
|
||||
|
||||
unsigned short rx_len;
|
||||
unsigned char g_rx_data[1000];
|
||||
int sock;
|
||||
int g_tx_enabled=0;
|
||||
int g_tx_waiting=0;
|
||||
int sdlc_exit=0;
|
||||
int max_sdlc_stations=MAX_INIT_SDLC_ADDR_CFG;
|
||||
/* Structure used to execute BiSync commands */
|
||||
wan_mbox_t mbox;
|
||||
|
||||
|
||||
sdlc_ch_t sdlc_ch_list[MAX_SDLC_LIST];
|
||||
|
||||
/*===================================================
|
||||
* Function Prototypes
|
||||
*==================================================*/
|
||||
int MakeConnection(char *, char *);
|
||||
void process_con( void);
|
||||
int sdlc_open_addr(int);
|
||||
int sdlc_close_all_ch (void);
|
||||
int sdlc_tx_all_ch (void);
|
||||
int sdlc_tx_all_enable (void);
|
||||
int sdlc_check_tx_all_ch(void);
|
||||
|
||||
|
||||
/*===================================================
|
||||
* DoCommand
|
||||
*
|
||||
* Execute a BiSync command directly on the
|
||||
* sangoma adapter. Refer to the
|
||||
* /usr/share/doc/wanpipe/bisync.pdf for the
|
||||
* list and explanation of BiSync commands.
|
||||
*
|
||||
*/
|
||||
|
||||
int DoCommand (wan_mbox_t *mbox)
|
||||
{
|
||||
return ioctl(sock, SIOC_WANPIPE_EXEC_CMD, mbox);
|
||||
}
|
||||
|
||||
/*===================================================
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*==================================================*/
|
||||
|
||||
int MakeConnection(char *r_name, char *i_name )
|
||||
{
|
||||
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", r_name, i_name);
|
||||
|
||||
strcpy( sa.sll_device, i_name);
|
||||
strcpy( sa.sll_card, r_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",i_name);
|
||||
exit(0);
|
||||
}
|
||||
printf("Socket bound to %s\n\n",i_name);
|
||||
|
||||
return (TRUE);
|
||||
|
||||
}
|
||||
|
||||
int sdlc_open_addr(int station_addr)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
||||
memset(&mbox,0,sizeof(mbox));
|
||||
|
||||
/* The user should add as many station as needed
|
||||
* at this point */
|
||||
mbox.wan_command=ADD_STATION;
|
||||
mbox.wan_data_len=0;
|
||||
mbox.wan_sdlc_address=station_addr;
|
||||
mbox.wan_sdlc_poll_interval=30;
|
||||
|
||||
if ((err=DoCommand(&mbox)) != 0){
|
||||
if (err != STATION_ALREADY_ADDED){
|
||||
printf("Failed to add station %i! rc=0x%X\n",
|
||||
station_addr,err);
|
||||
return FALSE;
|
||||
}else{
|
||||
printf("Station %i already added\n",
|
||||
mbox.wan_sdlc_address);
|
||||
}
|
||||
}else{
|
||||
printf("Added station %i\n",mbox.wan_sdlc_address);
|
||||
}
|
||||
|
||||
mbox.wan_command=ACTIVATE_STATION;
|
||||
mbox.wan_data_len=0;
|
||||
mbox.wan_sdlc_address=station_addr;
|
||||
mbox.wan_sdlc_poll_interval=30;
|
||||
|
||||
if ((err=DoCommand(&mbox)) != 0){
|
||||
if (err != STATION_ALREADY_ACTIVATED){
|
||||
printf("Failed to activate station %i! rc=0x%X\n",
|
||||
station_addr,err);
|
||||
return FALSE;
|
||||
}else{
|
||||
printf("Station %i already active\n",
|
||||
mbox.wan_sdlc_address);
|
||||
}
|
||||
}else{
|
||||
printf("Activated station %i\n",mbox.wan_sdlc_address);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void sdlc_close_addr(int station_addr)
|
||||
{
|
||||
int err;
|
||||
|
||||
memset(&mbox,0,sizeof(mbox));
|
||||
|
||||
/* The user should add as many station as needed
|
||||
* at this point */
|
||||
mbox.wan_command=DEACTIVATE_STATION;
|
||||
mbox.wan_data_len=0;
|
||||
mbox.wan_sdlc_address=station_addr;
|
||||
|
||||
if ((err=DoCommand(&mbox)) != 0){
|
||||
printf("Failed to deactivate station! 0x%X\n",err);
|
||||
}
|
||||
|
||||
memset(&mbox,0,sizeof(mbox));
|
||||
|
||||
/* The user should add as many station as needed
|
||||
* at this point */
|
||||
mbox.wan_command=DELETE_STATION;
|
||||
mbox.wan_data_len=0;
|
||||
mbox.wan_sdlc_address=station_addr;
|
||||
|
||||
if ((err=DoCommand(&mbox)) != 0){
|
||||
printf("Failed to delete station! 0x%X\n",err);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Station %i deleted!\n",station_addr);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* process_con
|
||||
*
|
||||
* 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 station PACKED;
|
||||
* unsigned char reserved[15] PACKED;
|
||||
* } api_rx_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* api_rx_hdr_t api_rx_hdr PACKED;
|
||||
* void * data PACKED;
|
||||
* } api_rx_element_t;
|
||||
*
|
||||
* station:
|
||||
* bisync station that received a packet
|
||||
*
|
||||
* TX_DATA:
|
||||
* --------
|
||||
* Each tx data packet MUST contain a 16 byte header!
|
||||
*
|
||||
* o Tx 16 byte data structure
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char station PACKED;
|
||||
* unsigned char misc_tx_rx_bits PACKED;
|
||||
* unsigned char reserved[14] PACKED;
|
||||
* } api_tx_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* api_tx_hdr_t api_tx_hdr PACKED;
|
||||
* void * data PACKED;
|
||||
* } api_tx_element_t;
|
||||
*
|
||||
* station:
|
||||
*
|
||||
* The station filed must be used to indicate
|
||||
* the station number on which the packet
|
||||
* should be transmitted.
|
||||
*
|
||||
* misc_tx_rx_bits:
|
||||
* The misc_tx_rx_bits can be used to control
|
||||
* the WRITE command.
|
||||
*
|
||||
* Refer to the /usr/share/doc/wanpipe/bisync.pdf
|
||||
*/
|
||||
|
||||
void process_con(void)
|
||||
{
|
||||
wan_api_t* wan_api;
|
||||
fd_set ready,oob,write;
|
||||
int err,i,j;
|
||||
unsigned char *data;
|
||||
struct timeval tv;
|
||||
|
||||
for (i=1;i<=max_sdlc_stations;i++){
|
||||
sdlc_ch_t *psdlc_ch = &sdlc_ch_list[i];
|
||||
|
||||
memset(psdlc_ch,0,sizeof(sdlc_ch_t));
|
||||
|
||||
err=sdlc_open_addr(i);
|
||||
if (err == FALSE){
|
||||
continue;
|
||||
}
|
||||
|
||||
psdlc_ch->addr=i;
|
||||
psdlc_ch->tx_len=MAX_TX_DATA;
|
||||
|
||||
/* Initialize the tx packet. The 16 byte header must
|
||||
* be inserted before tx data. */
|
||||
wan_api = (wan_api_t*)&psdlc_ch->tx_data[0];
|
||||
data = (unsigned char *)&wan_api->data;
|
||||
|
||||
/* Create a data packet, as an example
|
||||
* use addr value to fill the data packet */
|
||||
for (j=0;j<psdlc_ch->tx_len;j++){
|
||||
data[j] = (unsigned char)psdlc_ch->addr;
|
||||
}
|
||||
|
||||
wan_api->wan_api_sdlc_station = psdlc_ch->addr;
|
||||
wan_api->wan_api_sdlc_pf = 0;
|
||||
wan_api->wan_api_sdlc_poll_interval = 0;
|
||||
wan_api->wan_api_sdlc_general_mb_byte = 0;
|
||||
|
||||
psdlc_ch->tx_delay = MAX_TX_DELAY;
|
||||
psdlc_ch->pkts_to_tx = MAX_INIT_TX_CNT;
|
||||
psdlc_ch->tx_delay_enabled = 0;
|
||||
psdlc_ch->tx_count = 1;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&ready);
|
||||
FD_SET(sock,&oob);
|
||||
|
||||
sdlc_check_tx_all_ch();
|
||||
|
||||
if (g_tx_enabled){
|
||||
FD_SET(sock,&write);
|
||||
tv.tv_sec=0;
|
||||
tv.tv_usec=10000;
|
||||
|
||||
}else if (g_tx_waiting){
|
||||
tv.tv_sec=0;
|
||||
tv.tv_usec=10000;
|
||||
}else{
|
||||
/* Nothing to Tx, thus use a large
|
||||
* select() timeout value */
|
||||
tv.tv_sec=5;
|
||||
tv.tv_usec=10000;
|
||||
}
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active sockets.
|
||||
*/
|
||||
|
||||
if (sdlc_exit){
|
||||
break;
|
||||
}
|
||||
|
||||
err = select(sock + 1,&ready, &write, &oob, &tv);
|
||||
|
||||
if (err > 0){
|
||||
|
||||
if (FD_ISSET(sock,&oob)){
|
||||
err=recv(sock, g_rx_data, sizeof(g_rx_data), MSG_OOB);
|
||||
perror("Recv OOB");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for rx packets */
|
||||
if (FD_ISSET(sock,&ready)){
|
||||
|
||||
err = recv(sock, g_rx_data, sizeof(g_rx_data), 0);
|
||||
|
||||
/* err indicates bytes received */
|
||||
if(err > 0) {
|
||||
|
||||
/* Rx packet recevied OK
|
||||
* Each rx packet will contain 16 bytes of
|
||||
* rx header, that must be removed. The
|
||||
* first byte of the 16 byte header will
|
||||
* indicate an error condition.
|
||||
*/
|
||||
|
||||
wan_api = (wan_api_t*)g_rx_data;
|
||||
|
||||
/* Check the packet length, after we remove
|
||||
* the 16 bytes rx header */
|
||||
rx_len = err - sizeof(wan_api_hdr_t);
|
||||
|
||||
if (wan_api->wan_api_sdlc_station > MAX_SDLC_LIST){
|
||||
printf("Warning: Rx data on invalid Station %i\n",
|
||||
wan_api->wan_api_sdlc_station);
|
||||
}else{
|
||||
|
||||
sdlc_ch_t *psdlc_ch = &sdlc_ch_list[wan_api->wan_api_sdlc_station];
|
||||
if (!psdlc_ch->addr){
|
||||
printf("Warning: Rx data on unconfig Station %i\n",
|
||||
wan_api->wan_api_sdlc_station);
|
||||
}else{
|
||||
psdlc_ch->rx_count++;
|
||||
|
||||
printf("Rx pkt %i, Station %i Pf=%i Len = %i\n",
|
||||
psdlc_ch->rx_count,
|
||||
wan_api->wan_api_sdlc_station,
|
||||
wan_api->wan_api_sdlc_pf,
|
||||
rx_len);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Check if the socket is ready to tx data */
|
||||
if (FD_ISSET(sock,&write)){
|
||||
|
||||
sdlc_tx_all_ch();
|
||||
|
||||
}
|
||||
|
||||
}else if (err == 0){
|
||||
|
||||
//printf("Select Timeout %li\n",get_cur_time());
|
||||
|
||||
}else{
|
||||
//perror("Select");
|
||||
}
|
||||
}
|
||||
|
||||
sdlc_close_all_ch();
|
||||
|
||||
close (sock);
|
||||
}
|
||||
|
||||
|
||||
void sig_tx(int sig)
|
||||
{
|
||||
sdlc_tx_all_enable();
|
||||
}
|
||||
|
||||
void sig_end(int sig)
|
||||
{
|
||||
sdlc_exit=1;
|
||||
}
|
||||
|
||||
int sdlc_close_all_ch (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=1;i<=max_sdlc_stations;i++){
|
||||
sdlc_ch_t *psdlc_ch = &sdlc_ch_list[i];
|
||||
|
||||
if (!psdlc_ch->addr){
|
||||
continue;
|
||||
}
|
||||
|
||||
sdlc_close_addr(psdlc_ch->addr);
|
||||
|
||||
psdlc_ch->addr=0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sdlc_tx_all_enable (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=1;i<=max_sdlc_stations;i++){
|
||||
sdlc_ch_t *psdlc_ch = &sdlc_ch_list[i];
|
||||
|
||||
if (!psdlc_ch->addr){
|
||||
continue;
|
||||
}
|
||||
|
||||
psdlc_ch->pkts_to_tx=100;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sdlc_check_tx_all_ch(void)
|
||||
{
|
||||
int i;
|
||||
unsigned long timeout=get_cur_time();
|
||||
unsigned int diff;
|
||||
|
||||
g_tx_enabled=0;
|
||||
g_tx_waiting=0;
|
||||
|
||||
for (i=1;i<=max_sdlc_stations;i++){
|
||||
sdlc_ch_t *psdlc_ch = &sdlc_ch_list[i];
|
||||
|
||||
if (!psdlc_ch->addr){
|
||||
continue;
|
||||
}
|
||||
|
||||
diff=timeout>=psdlc_ch->tx_cur_time?
|
||||
(timeout-psdlc_ch->tx_cur_time):
|
||||
((1000000-psdlc_ch->tx_cur_time)+timeout);
|
||||
#if 0
|
||||
printf("%s: Checking Addr %i Pkts=%i TxDelay=%i Timeout=%i CurTiem=%i Diff=%i\n",
|
||||
__FUNCTION__,
|
||||
psdlc_ch->addr,
|
||||
psdlc_ch->pkts_to_tx,
|
||||
psdlc_ch->tx_delay_enabled,
|
||||
timeout,
|
||||
psdlc_ch->tx_cur_time,
|
||||
diff);
|
||||
#endif
|
||||
|
||||
/* Check if there is anything to be
|
||||
* transmitted by any active channel,
|
||||
* if we find anything, enable transmission*/
|
||||
if (psdlc_ch->pkts_to_tx){
|
||||
|
||||
g_tx_waiting=1;
|
||||
|
||||
if (psdlc_ch->tx_delay_enabled){
|
||||
|
||||
/* The ch was busy last time we checked,thus
|
||||
* make sure that we wait for "delay" time
|
||||
* before we re-try */
|
||||
|
||||
if (psdlc_ch->tx_delay <= diff){
|
||||
psdlc_ch->tx_delay_enabled=0;
|
||||
g_tx_enabled=1;
|
||||
}
|
||||
}else{
|
||||
g_tx_enabled=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int sdlc_tx_all_ch (void)
|
||||
{
|
||||
int i;
|
||||
int err;
|
||||
|
||||
for (i=1;i<=max_sdlc_stations;i++){
|
||||
sdlc_ch_t *psdlc_ch = &sdlc_ch_list[i];
|
||||
|
||||
if (!psdlc_ch->addr){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (psdlc_ch->tx_delay_enabled){
|
||||
continue;
|
||||
}
|
||||
|
||||
err = send(sock,psdlc_ch->tx_data, psdlc_ch->tx_len + sizeof(wan_api_hdr_t), 0);
|
||||
|
||||
if (err > 0){
|
||||
|
||||
|
||||
/* Packet sent ok */
|
||||
printf("Packet Sent Station %i Len=%i Cnt=%i \n",
|
||||
psdlc_ch->addr,
|
||||
err-sizeof(wan_api_hdr_t),
|
||||
psdlc_ch->tx_count);
|
||||
|
||||
psdlc_ch->tx_count++;
|
||||
psdlc_ch->pkts_to_tx--;
|
||||
|
||||
}
|
||||
|
||||
if (errno == EBUSY){
|
||||
|
||||
//printf("Send busy, try again ...\n");
|
||||
|
||||
/* The driver is busy, we must requeue this
|
||||
* tx packet, and try resending it again
|
||||
* later. */
|
||||
|
||||
psdlc_ch->tx_cur_time = get_cur_time();
|
||||
psdlc_ch->tx_delay_enabled=1;
|
||||
#if 0
|
||||
printf("Packet Busy: Cnt=%i Time=%li\n",
|
||||
psdlc_ch->tx_count,
|
||||
get_cur_time());
|
||||
#endif
|
||||
}else{
|
||||
|
||||
/* Critical error: Should never happen */
|
||||
perror("Send");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call process_con() to read/write the socket
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
|
||||
if (argc > 3){
|
||||
max_sdlc_stations=atoi(argv[3]);
|
||||
}else if (argc > 2){
|
||||
max_sdlc_stations=MAX_INIT_SDLC_ADDR_CFG;
|
||||
}else{
|
||||
printf("\n");
|
||||
printf("Usage: sdlc_api <router name> <interface name> <num of stations>\n");
|
||||
printf("\n");
|
||||
printf(" eg: sdlc_api wanpipe1 sdlc0 2\n");
|
||||
printf("\n");
|
||||
printf(" Tx/Rx data on Station Station 1 and 2 \n\n");
|
||||
printf(" To enable Tx send a SIGUSR1 signal to sdlc_api\n");
|
||||
printf(" kill -SIGUSR1 $(pidof sdlc_api) or run ./tx_test\n\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
printf("Configuring for max sdlc stations = %i\n",max_sdlc_stations);
|
||||
|
||||
signal(SIGUSR1,sig_tx);
|
||||
signal(SIGINT,sig_end);
|
||||
signal(SIGTERM,sig_end);
|
||||
|
||||
proceed = MakeConnection(argv[1], argv[2]);
|
||||
if( proceed == TRUE ){
|
||||
process_con();
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
APIINC = /usr/src/linux/include
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: server_v1 \
|
||||
server_v2 \
|
||||
svc_client \
|
||||
pvc_client \
|
||||
hdlc_client
|
||||
@echo "Ok."
|
||||
|
||||
server_v1: server_v1.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
svc_client: svc_client.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
server_v2: server_v2.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
pvc_client: pvc_client.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
hdlc_client: hdlc_client.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
|
||||
clean:
|
||||
rm -f server_v1
|
||||
rm -f server_v2
|
||||
rm -f svc_client
|
||||
rm -f pvc_client
|
||||
rm -f hdlc_client
|
|
@ -0,0 +1,48 @@
|
|||
X25 API Package
|
||||
===============
|
||||
|
||||
Author: Nenad Corbic
|
||||
Date: Mar 6, 2000
|
||||
|
||||
|
||||
|
||||
The x25api package contains the sample client and server
|
||||
programs which should be used in application
|
||||
development.
|
||||
|
||||
|
||||
Contents of the API Package
|
||||
---------------------------
|
||||
|
||||
1) pthread/server.c : Mutli-Threaded server application using pthreads. The Pthread
|
||||
architecure should be used when dealing with large number
|
||||
of svcs.
|
||||
|
||||
2) server_v1.c : Multi-Process server application that waits for incoming calls.
|
||||
Once a call is accepted, it starts transmitting data.
|
||||
|
||||
3) server_v2.c : Single process server application that waits for incoming calls.
|
||||
Once a call is accepted, it start tx/rx data.
|
||||
|
||||
4) svc_client.c : Client application that places calls. Application
|
||||
doesn't wait for a call to be established; thus, multiple
|
||||
calls can be placed from a single process.
|
||||
|
||||
5) pvc_client.c: PVC Client/Server application. No call setup required,
|
||||
data is transmitted as soon as x25 link comes up.
|
||||
|
||||
6) debug.c: Debugging application. It lists all active WANPIPE socks
|
||||
and displays their state and % buffer usage.
|
||||
|
||||
7) hdlc_client.c: HDLC Client/Server application. HDLC uses LAPB HDLC
|
||||
protocol instead of full X25. A single PVC connection.
|
||||
In order to use the LAPB HDLC protocol, a LAPB option
|
||||
must be turned on in the WANPIPE configuration file.
|
||||
|
||||
|
||||
Programming Notes:
|
||||
------------------
|
||||
|
||||
Please refer to the /usr/local/wanrouter/doc/x25socket.pdf
|
||||
for programming instructions.
|
||||
|
|
@ -0,0 +1,449 @@
|
|||
/*****************************************************************************
|
||||
* hdlc_client.c X25API: HDLC ONLY : PVC Client Application
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 1995-2000 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_x25.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define MIN_FRM_LGTH 100
|
||||
#define MAX_FRM_LGTH MIN_FRM_LGTH+100
|
||||
|
||||
#define NO_FRMS_TO_TX 100000
|
||||
|
||||
#define MAX_X25_ADDR_SIZE 16
|
||||
#define MAX_X25_DATA_SIZE 129
|
||||
#define MAX_X25_FACL_SIZE 110
|
||||
|
||||
#define TIMEOUT 10
|
||||
|
||||
unsigned char Tx_data[MAX_FRM_LGTH];
|
||||
unsigned char Rx_data[MAX_FRM_LGTH];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection( char *, char * );
|
||||
void process_con( void);
|
||||
void setup_signal_handlers (void);
|
||||
void quit (int);
|
||||
void handle_oob_event(x25api_t* api_hdr);
|
||||
|
||||
|
||||
/* Defined global so it would only get allocated once.
|
||||
* If it was defined in MakeConnection() function it
|
||||
* would be allocated and dealocated every time we
|
||||
* run that function.
|
||||
*/
|
||||
|
||||
int sock;
|
||||
|
||||
int send_ok=0;
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call send_socket() to transmit data
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
|
||||
if (argc < 3){
|
||||
printf("Usage: ./pvc_client <card name> <interface name>\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (argc == 4){
|
||||
send_ok=1;
|
||||
}
|
||||
|
||||
proceed = MakeConnection(argv[2],argv[1]);
|
||||
if (proceed == TRUE){
|
||||
process_con( );
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*/
|
||||
|
||||
int MakeConnection (char *int_name, char *card_name)
|
||||
{
|
||||
struct wan_sockaddr_ll sa;
|
||||
int err=0;
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
|
||||
/* Create a new socket */
|
||||
sock = socket( AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( sock < 0 ) {
|
||||
perror("Socket");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Fill in binding information
|
||||
* before we use connect() system call
|
||||
* a socket must be binded into a
|
||||
* network interface defined in wanpipe#.conf.
|
||||
*
|
||||
* Card name must be supplied as well. In
|
||||
* this case the user supplies the name
|
||||
* eg: wanpipe1.
|
||||
*/
|
||||
sa.sll_family = AF_WANPIPE;
|
||||
sa.sll_protocol = htons(X25_PROT);
|
||||
strcpy(sa.sll_device, int_name);
|
||||
strcpy(sa.sll_card, card_name);
|
||||
|
||||
|
||||
/* Bind a sock to */
|
||||
if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){
|
||||
perror("bind");
|
||||
printf("Failed to bind socket to %s interface\n",int_name);
|
||||
close(sock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We must use connect to bring the LAPB HDLC link
|
||||
* up. The connect will block until the link comes up */
|
||||
err=connect(sock,(struct sockaddr *)&sa,sizeof(struct wan_sockaddr_ll));
|
||||
if (err == 0){
|
||||
printf("Connect OK\n");
|
||||
}else{
|
||||
perror("Connect: ");
|
||||
printf("Connect BAD, %i\n",err);
|
||||
close(sock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************
|
||||
* process_con
|
||||
*
|
||||
* o Send and Receive data via socket
|
||||
* o Create a tx packet using x25api_t data type.
|
||||
* o Both the tx and rx packets contains 16 bytes headers
|
||||
* in front of the real data. It is the responsibility
|
||||
* of the applicatino to insert this 16 bytes on tx, and
|
||||
* remove the 16 bytes on rx.
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* o 16 byte Header: data structure:
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char qdm PACKED; Q/D/M bits
|
||||
* unsigned char cause PACKED; cause field
|
||||
* unsigned char diagn PACKED; diagnostics
|
||||
* unsigned char pktType PACKED;
|
||||
* unsigned short length PACKED;
|
||||
* unsigned char result PACKED;
|
||||
* unsigned short lcn PACKED;
|
||||
* char reserved[7] PACKED;
|
||||
* }x25api_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* x25api_hdr_t hdr PACKED;
|
||||
* char data[X25_MAX_DATA] PACKED;
|
||||
* }x25api_t;
|
||||
*
|
||||
* TX DATA:
|
||||
* --------
|
||||
* Each tx data packet must contain the above 16 byte header!
|
||||
*
|
||||
* QDM: Represents PF variable:
|
||||
*
|
||||
* Thus, if you set the QDM to 1, the driver will set the
|
||||
* PF bit which will request acknowledgement of each
|
||||
* packet sent.
|
||||
*
|
||||
* RX DATA:
|
||||
* --------
|
||||
* Each rx data will contain the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte rx header, are the
|
||||
* LCN and QDM bytes.
|
||||
*
|
||||
* QDM: It represents PF variable:
|
||||
*
|
||||
*
|
||||
* OOB DATA:
|
||||
* ---------
|
||||
* The OOB (out of band) data is used by the driver to
|
||||
* indicate x25 events for the active channel:
|
||||
* clear call, or restarts.
|
||||
*
|
||||
* Each OOB packet contains the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte oob header, are the
|
||||
* pktType, cause and diagn bytes.
|
||||
*
|
||||
* pktType = event type (ex Clear Call, Restart ...)
|
||||
* cause = x25 cause of the event
|
||||
* diagn = x25 diagnostic information used to determine
|
||||
* the cause of the event.
|
||||
*
|
||||
* Upon receiving an event, the sock should be considered
|
||||
* DEAD!!! Meaning it must be closed using the close()
|
||||
* function.
|
||||
*/
|
||||
|
||||
void process_con(void)
|
||||
{
|
||||
unsigned int Tx_count=0;
|
||||
unsigned short Tx_lgth,timeout=0;
|
||||
int err=0, i, Rx_count=0;
|
||||
struct timeval tv;
|
||||
x25api_t* api_tx_el;
|
||||
fd_set writeset,readset,oobset;
|
||||
|
||||
Tx_lgth = MIN_FRM_LGTH;
|
||||
|
||||
api_tx_el = (x25api_t *)Tx_data;
|
||||
|
||||
/* Reset the PF Bit */
|
||||
api_tx_el->hdr.qdm = 0;
|
||||
|
||||
/* Fill in the packet data */
|
||||
for (i=0; i<Tx_lgth ; i++){
|
||||
api_tx_el->data[i] = (unsigned char) i;
|
||||
}
|
||||
|
||||
//printf("Starting Select\n");
|
||||
|
||||
for(;;) {
|
||||
fflush(stdout);
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_ZERO(&writeset);
|
||||
|
||||
FD_SET(sock,&oobset);
|
||||
#if 1
|
||||
FD_SET(sock,&readset);
|
||||
if (send_ok){
|
||||
FD_SET(sock,&writeset);
|
||||
}
|
||||
#endif
|
||||
/* This must be within the loop */
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = TIMEOUT;
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if already queued packet
|
||||
* cannot be sent
|
||||
*/
|
||||
if((err=select(sock+1, &readset, &writeset, &oobset, NULL))){
|
||||
|
||||
//printf("Select\n");
|
||||
|
||||
if (FD_ISSET(sock,&oobset)){
|
||||
|
||||
printf("OOB\n");
|
||||
/* The OOB Message will indicate that an
|
||||
* asynchronous event occured. The applicaton
|
||||
* must stop everything and check the state of
|
||||
* the link. Since link might
|
||||
* have gone down */
|
||||
|
||||
/* In this example I just exit. A real
|
||||
* application would check the state of the
|
||||
* sock first by reading the header information.
|
||||
*/
|
||||
|
||||
/* IMPORTANT:
|
||||
* If we fail to read the OOB message, we can
|
||||
* assume that the link is down. Thus, close
|
||||
* the socket and continue !!! */
|
||||
|
||||
err = recv(sock, Rx_data, sizeof(Rx_data), MSG_OOB);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
|
||||
/* The state of the socket is disconnected.
|
||||
* We must close the socket and continue with
|
||||
* operation */
|
||||
printf("Failed to receive OOB %i , %i\n", Rx_count, err);
|
||||
break;
|
||||
}else{
|
||||
api_tx_el = (x25api_t *)Rx_data;
|
||||
handle_oob_event(api_tx_el);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&readset)){
|
||||
|
||||
err = recv(sock, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
printf("Failed to rcv %i , %i\n", Rx_count, err);
|
||||
exit(1);
|
||||
}else{
|
||||
|
||||
/* Every received packet comes with the 16
|
||||
* bytes of header which driver adds on.
|
||||
* Header is structured as x25api_hdr_t.
|
||||
* (same as above)
|
||||
*/
|
||||
|
||||
x25api_hdr_t *api_data =
|
||||
(x25api_hdr_t *)Rx_data;
|
||||
|
||||
if (api_data->qdm & 0x01){
|
||||
/* More bit is set, thus
|
||||
* handle it accordingly */
|
||||
}
|
||||
#ifdef VEROBSE
|
||||
printf("\tReceive OK, size: %i, qdm %x,"
|
||||
"cause %x, diagn %x, cnt: %i\n",
|
||||
err, api_data->qdm,
|
||||
api_data->cause,
|
||||
api_data->diagn, ++Rx_count);
|
||||
#else
|
||||
putchar('R');
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock,&writeset)){
|
||||
|
||||
err = send(sock, Tx_data, Tx_lgth + sizeof(x25api_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err > 0 ) {
|
||||
#ifdef VERBOSE
|
||||
printf("Packet Sent %i\n",
|
||||
++Tx_count);
|
||||
#else
|
||||
putchar('T');
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop after number of frames */
|
||||
if(Tx_count == NO_FRMS_TO_TX)
|
||||
break;
|
||||
|
||||
timeout=0;
|
||||
}else{
|
||||
printf("Select error\n");
|
||||
if (err == 0){
|
||||
if (++timeout == 5){
|
||||
printf("Sock timeout exceeded MAXIMUM\n");
|
||||
sleep(5);
|
||||
break;
|
||||
}
|
||||
printf("Sock timeout try again !!!\n");
|
||||
}else{
|
||||
printf("Error in Select !!!\n");
|
||||
break;
|
||||
}
|
||||
}//if select
|
||||
}//for
|
||||
close(sock);
|
||||
}
|
||||
|
||||
void handle_oob_event(x25api_t* api_hdr)
|
||||
{
|
||||
|
||||
switch (api_hdr->hdr.pktType){
|
||||
|
||||
case ASE_RESET_RQST:
|
||||
printf("SockId=%i : OOB : Rx Reset Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
/* NOTE: we don't have to close the socket,
|
||||
* since the reset doesn't clear the call
|
||||
* however, it means that there is something really
|
||||
* wrong and that data has been lost */
|
||||
return;
|
||||
|
||||
|
||||
case ASE_CLEAR_RQST:
|
||||
printf("SockId=%i : OOB : Rx Clear Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
|
||||
case ASE_RESTART_RQST:
|
||||
printf("SockId=%i : OOB : Rx Restart Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
case ASE_INTERRUPT:
|
||||
printf("SockId=%i : OOB : Rx Interrupt Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("SockId=%i : OOB : Rx Type=0x%02X : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.pktType,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
CC=g++
|
||||
SYSINC=/usr/src/linux/include
|
||||
APIINC=../../include
|
||||
CFLAGS=-O -I.. -D_REENTRANT -lpthread
|
||||
CFLAGS1=-w -c -D_REENTRANT -D_GNUC_ -D__LINUX__ -I$(SYSINC) -I$(APIINC)
|
||||
|
||||
server: bitmap.o server.o
|
||||
$(CC) $(CFLAGS) bitmap.o server.o -o server
|
||||
|
||||
server.o: server.h server.c
|
||||
$(CC) $(CFLAGS1) server.c
|
||||
|
||||
bitmap.o: bitmap.h bitmap.c
|
||||
$(CC) $(CFLAGS1) bitmap.c
|
||||
|
||||
clean:
|
||||
rm -f server
|
||||
rm *.o
|
|
@ -0,0 +1,135 @@
|
|||
// bitmap.c
|
||||
// Routines to manage a bitmap -- an array of bits each of which
|
||||
// can be either on or off. Represented as an array of integers.
|
||||
|
||||
#include "bitmap.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// BitMap::BitMap
|
||||
// Initialize a bitmap with "nitems" bits, so that every bit is clear.
|
||||
// it can be added somewhere on a list.
|
||||
// "nitems" is the number of bits in the bitmap.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
BitMap::BitMap(int nitems)
|
||||
{
|
||||
numBits = nitems;
|
||||
numWords = divRoundUp(numBits, BitsInWord);
|
||||
map = new unsigned int[numWords];
|
||||
if (pthread_mutex_init(&mut,NULL) != 0)
|
||||
perror("BitMap:BitMap");
|
||||
for (int i = 1; i <= numBits; i++)
|
||||
Clear(i);
|
||||
Mark(numBits);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// BitMap::~BitMap
|
||||
// De-allocate a bitmap.
|
||||
//----------------------------------------------------------------------
|
||||
BitMap::~BitMap()
|
||||
{
|
||||
delete map;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// BitMap::Set
|
||||
// Set the "nth" bit in a bitmap.
|
||||
// Makes this entry Unavailable
|
||||
// "which" is the number of the bit to be set.
|
||||
//----------------------------------------------------------------------
|
||||
void BitMap::Mark(int which)
|
||||
{
|
||||
assert(which >= 0 && which <= numBits);
|
||||
map[which / BitsInWord] |= 1 << (which % BitsInWord);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// BitMap::Clear
|
||||
// Clear the "nth" bit in a bitmap. (in other words, it's made available)
|
||||
// "which" is the number of the bit to be cleared.
|
||||
//----------------------------------------------------------------------
|
||||
void BitMap::Clear(int which)
|
||||
{
|
||||
assert(which > 0 && which <= numBits);
|
||||
map[which / BitsInWord] &= ~(1 << (which % BitsInWord));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// BitMap::Test
|
||||
// Return TRUE if the "nth" bit is set.
|
||||
// "which" is the number of the bit to be tested.
|
||||
//----------------------------------------------------------------------
|
||||
bool BitMap::Test(int which)
|
||||
{
|
||||
assert(which >= 0 && which <= numBits);
|
||||
|
||||
if (map[which / BitsInWord] & (1 << (which % BitsInWord)))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// BitMap::Find
|
||||
// Return the number of the first bit which is clear.
|
||||
// As a side effect, set the bit (mark it as in use).
|
||||
// (In other words, find and allocate a bit.)
|
||||
// If no bits are clear, return -1.
|
||||
//----------------------------------------------------------------------
|
||||
int BitMap::Find()
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&mut); // provides mutual exclusion
|
||||
|
||||
for (int i = 1; i <= numBits; i++)
|
||||
{
|
||||
if (!Test(i))
|
||||
{
|
||||
Mark(i); // found it,so mark it as busy
|
||||
pthread_mutex_unlock(&mut);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mut);
|
||||
return -1; // did not find an spot available, return -1
|
||||
|
||||
} // end of the Find method
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// BitMap::NumClear
|
||||
// Return the number of clear bits in the bitmap.
|
||||
// (In other words, how many bits are unallocated?)
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
int BitMap::NumClear()
|
||||
{
|
||||
int count=0;
|
||||
|
||||
for (int i=1; i <= numBits; i++)
|
||||
if (!Test(i))
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// BitMap::Print
|
||||
// Print the contents of the bitmap, for debugging.
|
||||
//
|
||||
// Could be done in a number of ways, but we just print the #'s of
|
||||
// all the bits that are set in the bitmap.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void BitMap::Print()
|
||||
{
|
||||
printf("Bitmap set:\n");
|
||||
for (int i = 1; i <= numBits; i++)
|
||||
if (Test(i))
|
||||
{
|
||||
printf("%d, ", i);
|
||||
if (i%25 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// bitmap.h
|
||||
// Data structures defining a bitmap -- an array of bits each of which
|
||||
// can be either on or off.
|
||||
//
|
||||
// Represented as an array of unsigned integers, on which we do
|
||||
// modulo arithmetic to find the bit we are interested in.
|
||||
//
|
||||
// The bitmap can be parameterized with with the number of bits being
|
||||
// managed.
|
||||
|
||||
|
||||
#ifndef BITMAP_H
|
||||
#define BITMAP_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fstream.h>
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
|
||||
// Definitions helpful for representing a bitmap as an array of integers
|
||||
|
||||
#define BitsInByte 8
|
||||
#define BitsInWord 32
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
// These two function were added from nachos/utility.h
|
||||
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
// Divide and either round up or down
|
||||
|
||||
#define divRoundDown(n,s) ((n) / (s))
|
||||
#define divRoundUp(n,s) (((n) / (s)) + ((((n) % (s)) > 0) ? 1 : 0))
|
||||
|
||||
// The following class defines a "bitmap" -- an array of bits,
|
||||
// each of which can be independently set, cleared, and tested.
|
||||
//
|
||||
// Most useful for managing the allocation of the elements of an array --
|
||||
// for instance, disk sectors, or main memory pages.
|
||||
// Each bit represents whether the corresponding sector or page is
|
||||
// in use or free.
|
||||
|
||||
class BitMap {
|
||||
|
||||
public:
|
||||
|
||||
BitMap(int nitems); // Initialize a bitmap, with "nitems" bits
|
||||
// initially, all bits are cleared.
|
||||
~BitMap(); // De-allocate bitmap
|
||||
|
||||
void Mark(int which); // Set the "nth" bit
|
||||
void Clear(int which); // Clear the "nth" bit
|
||||
bool Test(int which); // Is the "nth" bit set?
|
||||
int Find(); // Return the # of a clear bit, and as a side
|
||||
// effect, set the bit.
|
||||
// If no bits are clear, return -1.
|
||||
|
||||
int NumClear(); // Return the number of clear bits
|
||||
|
||||
void Print(); // Print contents of bitmap
|
||||
|
||||
private:
|
||||
|
||||
int numBits; // number of bits in the bitmap
|
||||
int numWords; // number of words of bitmap storage
|
||||
// (rounded up if numBits is not a
|
||||
// multiple of the number of bits in
|
||||
// a word)
|
||||
unsigned int *map; // bit storage
|
||||
|
||||
pthread_mutex_t mut;
|
||||
|
||||
// handle to accomplish
|
||||
// mutual exclusion
|
||||
|
||||
};
|
||||
|
||||
#endif // BITMAP_H
|
|
@ -0,0 +1,774 @@
|
|||
/*****************************************************************************
|
||||
* server.c X25 API: SVC Server Application
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 1995-2000 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.
|
||||
* ============================================================================
|
||||
* Due Credit :)
|
||||
* This sample utility was based on real-world
|
||||
* application written by:
|
||||
* Mauricio Rodriguez <Mauricio_Rodriguez@qs1.com>
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* The server.c utility will accept, user defined number, of
|
||||
* outgoing calls and tx/rx, user defined number, of packets on each
|
||||
* active svc.
|
||||
*
|
||||
* This utility should be used as an architectual model. It is up to
|
||||
* the user to handle all conditions of x25. Please refer to the
|
||||
* X25API programming manual for futher details.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "server.h"
|
||||
|
||||
|
||||
/*=============================================================
|
||||
* Main:
|
||||
*
|
||||
* o Make a listen socket connection to the driver.
|
||||
* o Wait for the connection to come in.
|
||||
* o Create a new socket for the incoming connection
|
||||
* using the accept() system call.
|
||||
* o Call the p-thread to handle the new connection
|
||||
*
|
||||
*============================================================*/
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void* pchnl_num;
|
||||
pthread_t threadID;
|
||||
int chnl,value,holdon = 0;
|
||||
pthread_attr_t attr;
|
||||
size_t stacksize = STACKSIZE;
|
||||
sock_dyn_status= new BitMap(MAX_CHNL+1);
|
||||
status = new BitMap(MAX_CHNL+1);
|
||||
X25_HDR = sizeof(x25api_hdr_t);
|
||||
struct sigaction sa_old;
|
||||
struct sigaction sa_new;
|
||||
char ptr4[20];
|
||||
int err = 0,max_err = 0;
|
||||
int next_chnl = 1,counter;
|
||||
struct wan_sockaddr_ll sa;
|
||||
x25api_t api_cmd;
|
||||
void* ptr;
|
||||
char i_name[25];
|
||||
bool found = FALSE;
|
||||
fd_set wait_for_call;
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (argc != 2){
|
||||
printf("Usage: ./server wanpipe# (#=1,2...)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* User defined wanpipe device */
|
||||
strncpy(i_name,argv[argc-1],(sizeof(i_name)-1));
|
||||
|
||||
|
||||
/* Initialize the signal handler
|
||||
* SIGINT = Ctrl C
|
||||
* If the user terminates the program, the
|
||||
* signal handler will cleanly close all sockets
|
||||
* before terminating.
|
||||
*/
|
||||
sa_new.sa_handler = cleanup;
|
||||
sa_new.sa_flags = 0;
|
||||
sigemptyset(&sa_new.sa_mask);
|
||||
sigaddset(&sa_new.sa_mask,SIGINT);
|
||||
sigaddset(&sa_new.sa_mask,SIGPIPE);
|
||||
sigaddset(&sa_new.sa_mask,SIGSEGV);
|
||||
if (sigaction(SIGSEGV,&sa_new,&sa_old) == ERROR)
|
||||
perror("main-sigaction");
|
||||
else
|
||||
puts("Success setting the SIGSEGV signal");
|
||||
if (sigaction(SIGINT,&sa_new,&sa_old) == ERROR)
|
||||
perror("main-sigaction");
|
||||
else
|
||||
puts("Success setting the signal SIGINT");
|
||||
|
||||
|
||||
/* Open a log file */
|
||||
if ((fd = fopen("server.log", "wr")) == NULL) {
|
||||
fprintf(stderr, "Unable to open log\n");
|
||||
exit(1);
|
||||
}
|
||||
sprintf(ptr4,"Main PID = %d\n",getpid());
|
||||
fwrite(ptr4,1,20,fd);
|
||||
|
||||
|
||||
printf("\n**************************************************\n");
|
||||
printf("***** STARTING WANPIPE1 PORT1 LIVE SWITCH ************\n");
|
||||
printf("**************************************************\n\n");
|
||||
|
||||
/* Initialize P-Threads */
|
||||
if (pthread_attr_init(&attr))
|
||||
perror("main-pthread_attr_init");
|
||||
|
||||
/* Initialize the thread stack size to 2MB
|
||||
* The kernel defaults the stack size to 8MB, this
|
||||
* however causes a problem when running 250+ threads.
|
||||
* By setting the stack size lower, we can have more
|
||||
* threads.
|
||||
*
|
||||
* WARNING: You must ensure that all you local
|
||||
* variables inside the thread do not exceed 2MB
|
||||
* In this application 512 KB should be sufficient.
|
||||
*
|
||||
* By default this option is NOT enabled */
|
||||
#ifdef STACK_SIZE_2MB
|
||||
if(pthread_attr_setstacksize(&attr,stacksize))
|
||||
perror("main-pthread_attr_setstacksize");
|
||||
#endif
|
||||
|
||||
/* For each channel setup semaphores that will
|
||||
* control each p-thread, and initialize the channel
|
||||
* private data */
|
||||
for (chnl = 1; chnl <= MAX_CHNL; chnl++)
|
||||
{
|
||||
sem_init(&semaphore[chnl],0,0);
|
||||
sem_init(&switch_up[chnl],0,0);
|
||||
chnl_c[chnl] = chnl;
|
||||
chnl_flag[chnl] = R_CALL;
|
||||
}
|
||||
|
||||
chnl_flag[0] = BUSY;
|
||||
|
||||
|
||||
/* For all possible channels (MAX_CHNL), create a p-thread.
|
||||
* Each p-thread will execute the process_con()
|
||||
* function.
|
||||
*/
|
||||
for (chnl = 1; chnl <= MAX_CHNL; chnl++)
|
||||
{
|
||||
pchnl_num = &chnl_c[chnl];
|
||||
|
||||
value = pthread_create(
|
||||
&threadID, // threadID if success
|
||||
&attr, // thread attributes
|
||||
process_con, // method to be run by this thread
|
||||
pchnl_num); // argument for new thread
|
||||
|
||||
if (value)
|
||||
perror("main-pthread_create,process_con");
|
||||
|
||||
} // end of for loop
|
||||
|
||||
|
||||
if (sigaction(SIGPIPE,&sa_new,&sa_old) == ERROR)
|
||||
perror("main-sigaction");
|
||||
else
|
||||
puts("Success setting the SIGPIPE signal");
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
|
||||
/* Create a new X25API socket */
|
||||
|
||||
soc = socket(AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( soc == SOCKET_ERROR ) {
|
||||
perror("server-Socket");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Fill in binding information.
|
||||
* Before we use listen() system call
|
||||
* a socket must be binded into a virtual
|
||||
* network interface svc_listen.
|
||||
*
|
||||
* Card name must be supplied as well. In
|
||||
* this case the user supplies the name
|
||||
* eg: wanpipe1.
|
||||
*/
|
||||
|
||||
sa.sll_family = AF_WANPIPE;
|
||||
sa.sll_protocol = htons(X25_PROT);
|
||||
strcpy((char*)sa.sll_device,"svc_listen");
|
||||
strcpy((char*)sa.sll_card,i_name);
|
||||
|
||||
/* Bind a sock using the above address structure */
|
||||
|
||||
if(bind(soc, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) == -1){
|
||||
perror("bind");
|
||||
printf("Failed to bind socket to %s interface\n",i_name);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
printf("SUCCESSFULL BINDING \n");
|
||||
|
||||
/* Put the sock into listening mode. Number 10 does not
|
||||
* mean anything, since number of connections is depended
|
||||
* on number of LCNs configured */
|
||||
|
||||
listen(soc,SOMAXCONN);
|
||||
|
||||
/* Start an infinite loop, and accept any incoming
|
||||
* calls. Once the call is received via accept() system
|
||||
* call, signal the appropriate p-thread to handle
|
||||
* the call acceptance as well as tx and rx data.
|
||||
*/
|
||||
|
||||
for (;;){
|
||||
|
||||
found = FALSE;
|
||||
holdon = 0;
|
||||
|
||||
/* Make sure there are free channels available
|
||||
* If there are not channels available, wait 300ms
|
||||
* and retry again. Once a channel is free, proceed
|
||||
* to wait for an incoming connection */
|
||||
while(!found) {
|
||||
if (chnl_flag[(next_chnl%MAX_CHNL)] == R_CALL) {
|
||||
chnl = next_chnl%MAX_CHNL;
|
||||
found = TRUE;
|
||||
next_chnl++;
|
||||
continue;
|
||||
}
|
||||
next_chnl++;
|
||||
if ((++holdon) > WAIT_FOR_A_WHILE){
|
||||
printf("Waiting until somebody frees a channel, should not be long...\n");
|
||||
holdon = 0;
|
||||
usleep(300);
|
||||
}
|
||||
}
|
||||
|
||||
/* Use select() to wait for an incoming call */
|
||||
FD_ZERO(&wait_for_call);
|
||||
FD_SET(soc,&wait_for_call);
|
||||
if (select(soc + 1, &wait_for_call, NULL, NULL,NULL)){
|
||||
|
||||
if (FD_ISSET(soc,&wait_for_call)){
|
||||
|
||||
/* accept() will create a new socket for an
|
||||
* incoming call. We must parse the
|
||||
* called and calling data and determine if we
|
||||
* want to accept the call. This will be done
|
||||
* in a P-thread */
|
||||
sock[chnl] = accept(soc,NULL,NULL);
|
||||
}else{
|
||||
sock[chnl] == INVALID_SOCKET;
|
||||
}
|
||||
}else{
|
||||
/* Error in select() */
|
||||
sock[chnl] == INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if (sock[chnl] == INVALID_SOCKET) {
|
||||
printf("\nSERVER failing calls... exiting \n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
/* The accept() call has created the new socket
|
||||
* for an incoming call. Use sem_pose() to
|
||||
* wake up an appropriate thread, so it can
|
||||
* handle the new connection. The process_con()
|
||||
* function is used to handle new connections.
|
||||
*/
|
||||
chnl_flag[chnl] = BUSY;
|
||||
|
||||
if(sem_post(&semaphore[chnl]) == ERROR)
|
||||
perror("server:sem_post");
|
||||
|
||||
}
|
||||
|
||||
printf("*** SERVER thread has EXITED ... Terminating application .... \n");
|
||||
|
||||
return 0;
|
||||
} // end of the main function
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************
|
||||
* process_con
|
||||
*
|
||||
* o Send and Receive data via socket
|
||||
* o Create a tx packet using x25api_t data type.
|
||||
* o Both the tx and rx packets contains 16 bytes headers
|
||||
* in front of the real data. It is the responsibility
|
||||
* of the applicatino to insert this 16 bytes on tx, and
|
||||
* remove the 16 bytes on rx.
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* o 16 byte Header: data structure:
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char qdm PACKED; Q/D/M bits
|
||||
* unsigned char cause PACKED; cause field
|
||||
* unsigned char diagn PACKED; diagnostics
|
||||
* unsigned char pktType PACKED;
|
||||
* unsigned short length PACKED;
|
||||
* unsigned char result PACKED;
|
||||
* unsigned short lcn PACKED;
|
||||
* char reserved[7] PACKED;
|
||||
* }x25api_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* x25api_hdr_t hdr PACKED;
|
||||
* char data[X25_MAX_DATA] PACKED;
|
||||
* }x25api_t;
|
||||
*
|
||||
* TX DATA:
|
||||
* --------
|
||||
* Each tx data packet must contain the above 16 byte header!
|
||||
*
|
||||
* Only relevant byte in the 16 byte tx header, is the
|
||||
* QDM byte. The driver will look at this byte to determine
|
||||
* if the Mbit (more data bit) should be set.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* RX DATA:
|
||||
* --------
|
||||
* Each rx data will contain the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte rx header, are the
|
||||
* LCN and QDM bytes.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* LCN = contains the lcn number for the rx frame.
|
||||
*
|
||||
* OOB DATA:
|
||||
* ---------
|
||||
* The OOB (out of band) data is used by the driver to
|
||||
* indicate x25 events for the active channel:
|
||||
* clear call, or restarts.
|
||||
*
|
||||
* Each OOB packet contains the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte oob header, are the
|
||||
* pktType, cause and diagn bytes.
|
||||
*
|
||||
* pktType = event type (ex Clear Call, Restart ...)
|
||||
* cause = x25 cause of the event
|
||||
* diagn = x25 diagnostic information used to determine
|
||||
* the cause of the event.
|
||||
*
|
||||
* Upon receiving an event, the sock should be considered
|
||||
* DEAD!!! Meaning it must be closed using the close()
|
||||
* function.
|
||||
*/
|
||||
|
||||
|
||||
void* process_con(void* threadID)
|
||||
{
|
||||
int chnl =*(int *)threadID;
|
||||
int err,ready=0,i = 0;
|
||||
fd_set readset,oobset,writeset;
|
||||
|
||||
int bytes_read,bytes_sent;
|
||||
unsigned char buffer[BUFFER_SIZE];
|
||||
unsigned char tx_buffer[BUFFER_SIZE];
|
||||
char ptr[20];
|
||||
struct timeval timeout;
|
||||
unsigned short Tx_lgth;
|
||||
|
||||
x25api_t* api_rx_el;
|
||||
x25api_t* api_tx_el;
|
||||
x25api_hdr_t *api_data;
|
||||
|
||||
void* ptr3;
|
||||
enum more {ON = 1,OFF = 0};
|
||||
x25api_t api_cmd;
|
||||
|
||||
pthread_detach(pthread_self()); // free system resources as soon as it exits
|
||||
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
sprintf(ptr,"pro_con PID = %d\n",getpid());
|
||||
fwrite(ptr,1,20,fd);
|
||||
|
||||
/* Initialize and create a tx packet */
|
||||
memset(tx_buffer,0,sizeof(tx_buffer));
|
||||
|
||||
api_tx_el=(x25api_t*)tx_buffer;
|
||||
|
||||
/* This is how to set more bit
|
||||
* for the current packet */
|
||||
#ifdef TX_MORE_BIT_SET
|
||||
api_tx_el->hdr.qdm = 0x01
|
||||
#endif
|
||||
|
||||
for (i=0; i<Tx_lgth ; i++){
|
||||
api_tx_el->data[i] = (unsigned char) i;
|
||||
}
|
||||
|
||||
|
||||
/* Each P-thread will call this function */
|
||||
|
||||
for(;;) {
|
||||
|
||||
waiting:
|
||||
/* Wait for a call to be detected by the main process.
|
||||
* Once a new socket is created by the accept() system call.
|
||||
* the main process will wake us up.
|
||||
*/
|
||||
sem_wait(&semaphore[chnl]); // is connection UP ?
|
||||
|
||||
/* The call is currently pending. Thus, check the
|
||||
* x25 address information and accept the call */
|
||||
if (accept_call (sock[chnl], chnl, &api_cmd) != 0)
|
||||
goto waiting;
|
||||
|
||||
sock_dyn_status->Mark(chnl);
|
||||
status->Mark(chnl);
|
||||
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_ZERO(&writeset);
|
||||
|
||||
for(;;) {
|
||||
|
||||
FD_SET(sock[chnl],&readset);
|
||||
FD_SET(sock[chnl],&oobset);
|
||||
#ifdef ENABLE_WRITE
|
||||
FD_SET(sock[chnl],&writeset);
|
||||
#endif
|
||||
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active x25 sockets.
|
||||
*
|
||||
* If the NONBLOCKING option has been used during connect()
|
||||
* the select will wait untill the channel is connected
|
||||
* (i.e. accept has been received). Once the channel is connected
|
||||
* the tx and rx will start. However, if the call is cleared for
|
||||
* any reason, the OOB message will indicate that event.
|
||||
*/
|
||||
|
||||
|
||||
ready = select(sock[chnl]+1,&readset,&writeset,&oobset,&timeout);
|
||||
|
||||
if(ready) {
|
||||
|
||||
/* First check for OOB messages */
|
||||
|
||||
if (FD_ISSET(sock[chnl], &oobset)){
|
||||
|
||||
/* The OOB Message will indicate that an
|
||||
* asynchronous event occured. The applicaton
|
||||
* must stop everything and check the state of
|
||||
* the link. Since link might
|
||||
* have gone down */
|
||||
|
||||
/* In this example I just exit. A real
|
||||
* application would check the state of the
|
||||
* sock first by reading the header information.
|
||||
*/
|
||||
|
||||
/* IMPORTANT:
|
||||
* If we fail to read the OOB message, we can
|
||||
* assume that the link is down. Thus, close
|
||||
* the socket and continue !!! */
|
||||
|
||||
bytes_read = recv(sock[chnl],(char*)&buffer,BUFFER_SIZE,MSG_OOB);
|
||||
|
||||
if(bytes_read < 0 ) {
|
||||
/* The state of the socket is disconnected.
|
||||
* We must close the socket and continue with
|
||||
* operation */
|
||||
printf("# %d has been CLEARED OOB FAILURE\n",chnl);
|
||||
close_connection(chnl,readset);
|
||||
goto waiting;
|
||||
}
|
||||
|
||||
api_rx_el = (x25api_t *)buffer;
|
||||
|
||||
|
||||
handle_oob_event(api_rx_el, chnl);
|
||||
|
||||
memset(&api_cmd, 0, sizeof(x25api_t));
|
||||
if(ioctl(sock[chnl],SIOC_WANPIPE_SOCK_STATE,&api_cmd) == 1){ // Disconnected !
|
||||
close_connection(chnl,readset);
|
||||
goto waiting;
|
||||
}
|
||||
|
||||
/* Do what ever you have to do to handle
|
||||
* this condiditon */
|
||||
|
||||
|
||||
} // end of oobset read
|
||||
|
||||
|
||||
|
||||
/* Check for RX data */
|
||||
|
||||
if (FD_ISSET(sock[chnl], &readset)) {
|
||||
|
||||
bytes_read = recv(sock[chnl],(char*)&buffer,BUFFER_SIZE,MSG_NOSIGNAL);
|
||||
switch(bytes_read)
|
||||
{
|
||||
case SOCKET_ERROR: case 0:
|
||||
printf("# %d SOCKET_ERROR ....\n",sock[chnl]);
|
||||
close_connection(chnl,readset);
|
||||
goto waiting;
|
||||
|
||||
default:
|
||||
|
||||
/* Packet received OK !
|
||||
*
|
||||
* Every received packet comes with the 16
|
||||
* bytes of header which driver adds on.
|
||||
* Header is structured as x25api_hdr_t.
|
||||
* (same as above)
|
||||
*/
|
||||
|
||||
api_data = (x25api_hdr_t *)buffer;
|
||||
|
||||
if (api_data->qdm & 0x01){
|
||||
/* More bit is set, thus
|
||||
* handle it accordingly */
|
||||
}
|
||||
|
||||
printf("Rx: Size=%i, Mbit=%i, Lcn=%i\n",
|
||||
bytes_read,
|
||||
(api_data->qdm & 0x01),
|
||||
api_data->lcn);
|
||||
} // end of switch
|
||||
|
||||
}
|
||||
|
||||
/* Check if the socket is ready for writing */
|
||||
if (FD_ISSET(sock[chnl], &writeset)) {
|
||||
|
||||
/* Socket is ready to tx data */
|
||||
|
||||
/* The tx packet length contains the 16 byte
|
||||
* header. The tx packet was created above. */
|
||||
|
||||
bytes_sent = send(sock[chnl], tx_buffer,
|
||||
Tx_lgth + sizeof(x25api_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err>0){
|
||||
printf("SockId=%i : TX\n",
|
||||
sock[chnl]);
|
||||
}
|
||||
|
||||
/* If err<=0 it means that the send failed and that
|
||||
* driver is busy. Thus, the packet should be
|
||||
* requeued for re-transmission on the next
|
||||
* try !!!!
|
||||
*/
|
||||
}
|
||||
|
||||
} // end of ready
|
||||
else {
|
||||
|
||||
/* select() timeout condition */
|
||||
timeout.tv_sec = 1 ;
|
||||
if(!sock_dyn_status->Test(chnl)) {
|
||||
memset(&api_cmd, 0, sizeof(x25api_t));
|
||||
api_cmd.hdr.qdm = 0x00;
|
||||
ioctl(sock[chnl],SIOC_WANPIPE_CLEAR_CALL,&api_cmd);
|
||||
close_connection(chnl,readset);
|
||||
goto waiting;
|
||||
}
|
||||
}
|
||||
|
||||
}// end of the inner for statement
|
||||
|
||||
}// end of the outter for statement
|
||||
|
||||
exiting:
|
||||
|
||||
printf("%d is exiting ...\n",getpid());
|
||||
return ptr3;
|
||||
|
||||
} // end of the process_con
|
||||
|
||||
void close_connection(int chnl,fd_set readset)
|
||||
{
|
||||
if(close(sock[chnl]) == ERROR)
|
||||
perror("process_con-closeDynastarsocket");
|
||||
FD_CLR(sock[chnl],&readset);
|
||||
sock_dyn_status->Clear(chnl);
|
||||
status->Clear(chnl);
|
||||
chnl_flag[chnl] = R_CALL;
|
||||
}
|
||||
|
||||
|
||||
static void cleanup(int signo)
|
||||
{
|
||||
int static count = 0,count1 = 0;
|
||||
|
||||
switch(signo){
|
||||
|
||||
case SIGPIPE:
|
||||
|
||||
printf("SIGPIPE signal raised by process PID = %d \n",getpid());
|
||||
exit(-1);
|
||||
break;
|
||||
|
||||
case SIGSEGV:
|
||||
|
||||
printf("SIGSEGV signal raised by process PID = %d \n",getpid());
|
||||
fclose(fd);
|
||||
exit(-1);
|
||||
break;
|
||||
|
||||
case SIGINT:
|
||||
|
||||
if (++count == 1) {
|
||||
//printf("%d CLEANING upon Ctrl-C ...\n",getpid());
|
||||
for(int chnl = 1 ; chnl < MAX_CHNL; chnl++)
|
||||
if (status->Test(chnl))
|
||||
{
|
||||
printf("%d closing open sockets \n");
|
||||
close(sock[chnl]);
|
||||
}
|
||||
close(soc);
|
||||
fclose(fd);
|
||||
printf("EXITING ...\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
} // end of the switch
|
||||
|
||||
} // end of the cleanup method
|
||||
|
||||
|
||||
|
||||
int accept_call (int sock, int chnl, x25api_t *api_cmd)
|
||||
{
|
||||
int err;
|
||||
int counter;
|
||||
|
||||
/* Reset the api command structure */
|
||||
memset(api_cmd, 0, sizeof(x25api_t));
|
||||
|
||||
/* The GET CALL DATA ioctl call will write in the
|
||||
* incoming call data into api_cmd structure. Once
|
||||
* we have call data information, it is up to the
|
||||
* user to accept or clear call. */
|
||||
|
||||
if ((err=ioctl(sock,SIOC_WANPIPE_GET_CALL_DATA,api_cmd)) < 0){
|
||||
printf ("Get Call Data Failed %i\n",err);
|
||||
close(sock);
|
||||
return -EINVAL;
|
||||
}else{
|
||||
printf("SockId=%d : Incoming Call on Lcn %i\n",chnl,api_cmd->hdr.lcn);
|
||||
}
|
||||
|
||||
|
||||
/* Copy the incoming called address
|
||||
* The called address format is:
|
||||
* -d<called address> -s<calling address> -u<user data>
|
||||
* In this case we are just checking the called address */
|
||||
memset(&called_address[chnl][0],0x0,15);
|
||||
|
||||
counter = -1;
|
||||
while(++counter < min(api_cmd->hdr.length,15)){
|
||||
if (api_cmd->data[2+counter] == ' ')
|
||||
break;
|
||||
|
||||
called_address[chnl][counter] = api_cmd->data[2+counter];
|
||||
}
|
||||
|
||||
//printf ("Incoming Called Address : %s\n",counter,called_address[chnl]);
|
||||
|
||||
/* In this case I don't care about the called address,
|
||||
* I will accept any call, thus proceed to accept the call */
|
||||
if ((err=ioctl(sock,SIOC_WANPIPE_ACCEPT_CALL,0)) != 0){
|
||||
printf("Accept failed err=%i lcn=%i\n",err,api_cmd->hdr.lcn);
|
||||
close(sock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void handle_oob_event(x25api_t* api_hdr, int sk_index)
|
||||
{
|
||||
|
||||
switch (api_hdr->hdr.pktType){
|
||||
|
||||
case ASE_RESET_RQST:
|
||||
printf("SockId=%i : OOB : Rx Reset Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock[sk_index],
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
/* NOTE: we don't have to close the socket,
|
||||
* since the reset doesn't clear the call
|
||||
* however, it means that there is something really
|
||||
* wrong and that data has been lost */
|
||||
return;
|
||||
|
||||
|
||||
case ASE_CLEAR_RQST:
|
||||
printf("SockId=%i : OOB : Rx Clear Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock[sk_index],
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
|
||||
case ASE_RESTART_RQST:
|
||||
printf("SockId=%i : OOB : Rx Restart Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock[sk_index],
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
case ASE_INTERRUPT:
|
||||
printf("SockId=%i : OOB : Rx Interrupt Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock[sk_index],
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("SockId=%i : OOB : Rx Type=0x%02X : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock[sk_index],
|
||||
api_hdr->hdr.pktType,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
#ifndef _SERVER_H
|
||||
#define _SERVER_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/poll.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_x25.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#include "bitmap.h"
|
||||
|
||||
#define INVALID_SOCKET -1
|
||||
#define ERROR -1
|
||||
#define SOCKET_ERROR -1
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define MAX_CHNL 128
|
||||
#define STACKSIZE 0x200000 // 2 Mb STACK SIZE
|
||||
#define BUFFER_SIZE 1024
|
||||
#define MAX_FRM_LGTH 1008
|
||||
#define WAIT_FOR_A_WHILE 2
|
||||
// thread declarations
|
||||
|
||||
void* process_con(void* arg);
|
||||
void* switch_recv(void* threadID);
|
||||
|
||||
// function declarations
|
||||
|
||||
int connect_switch(int switch_num,int which);
|
||||
static void cleanup(int signo);
|
||||
void close_connection(int,fd_set);
|
||||
void printing(unsigned char*,int);
|
||||
int find_separator(char*ptr);
|
||||
int accept_call (int sock, int chnl, x25api_t *api_cmd);
|
||||
void handle_oob_event(x25api_t* api_hdr, int sk_index);
|
||||
|
||||
|
||||
|
||||
// variable declarations
|
||||
|
||||
int sock[MAX_CHNL+1];
|
||||
enum { BUSY = 0 , R_CALL = 1};
|
||||
int chnl_flag[MAX_CHNL+1];
|
||||
int switch_socket[MAX_CHNL+1];
|
||||
sem_t semaphore[MAX_CHNL+1],switch_up[MAX_CHNL+1];
|
||||
char called_address[MAX_CHNL+1][15];
|
||||
pthread_t threadID[MAX_CHNL+1];
|
||||
pthread_t threadID1[MAX_CHNL+1];
|
||||
int chnl_c[MAX_CHNL+1],soc;
|
||||
struct sockaddr_in ClientAddr,ClientAddr2;
|
||||
BitMap *status,*sock_dyn_status;
|
||||
int X25_HDR,who = 0;
|
||||
char SWITCH06[] = "10.1.3.29"; //switch06-nt.qs1.com
|
||||
char SWITCH10[] = "10.1.3.33"; //switch10-nt.qs1.com
|
||||
FILE *fd;
|
||||
|
||||
#endif // _SERVER_H
|
||||
|
|
@ -0,0 +1,478 @@
|
|||
/*****************************************************************************
|
||||
* pvc_client.c X25API: PVC Client Application
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 1995-2000 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_x25.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define MIN_FRM_LGTH 10
|
||||
#define MAX_FRM_LGTH 1400
|
||||
#define NO_FRMS_TO_TX 100
|
||||
|
||||
#define MAX_X25_ADDR_SIZE 16
|
||||
#define MAX_X25_DATA_SIZE 129
|
||||
#define MAX_X25_FACL_SIZE 110
|
||||
|
||||
#define TIMEOUT 10
|
||||
|
||||
unsigned char Tx_data[MIN_FRM_LGTH + sizeof(x25api_hdr_t)];
|
||||
|
||||
unsigned char Rx_data[1000];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection( char *, char * );
|
||||
void process_con( void);
|
||||
void setup_signal_handlers (void);
|
||||
void quit (int);
|
||||
void handle_oob_event(x25api_t* api_hdr);
|
||||
|
||||
|
||||
/* Defined global so it would only get allocated once.
|
||||
* If it was defined in MakeConnection() function it
|
||||
* would be allocated and dealocated every time we
|
||||
* run that function.
|
||||
*/
|
||||
|
||||
int sock;
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call send_socket() to transmit data
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
|
||||
if (argc != 3){
|
||||
printf("Usage: ./pvc_client <card name> <interface name>\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
proceed = MakeConnection(argv[argc-1],argv[argc-2]);
|
||||
if (proceed == TRUE){
|
||||
process_con( );
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* (Interface name is supplied by the user)
|
||||
*/
|
||||
|
||||
int MakeConnection (char *int_name, char *card_name)
|
||||
{
|
||||
int len = sizeof(struct wan_sockaddr_ll);
|
||||
int err = 0;
|
||||
struct wan_sockaddr_ll sa;
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
|
||||
printf("Would you like to start again (Y/N)");
|
||||
if (getchar() != 'y')
|
||||
exit(1);
|
||||
|
||||
/* Create a new socket */
|
||||
sock = socket( AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( sock < 0 ) {
|
||||
perror("Socket");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fill in binding information
|
||||
* before we use connect() system call
|
||||
* a socket must be binded into a
|
||||
* network interface defined in wanpipe#.conf.
|
||||
*
|
||||
* Card name must be supplied as well. In
|
||||
* this case the user supplies the name
|
||||
* eg: wanpipe1.
|
||||
*/
|
||||
sa.sll_family = AF_WANPIPE;
|
||||
sa.sll_protocol = htons(0x16);
|
||||
strcpy(sa.sll_device, int_name);
|
||||
strcpy(sa.sll_card, card_name);
|
||||
|
||||
|
||||
/* Bind a sock to */
|
||||
if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) == -1){
|
||||
perror("bind");
|
||||
printf("Failed to bind socket to %s interface\n",int_name);
|
||||
close(sock);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* The sa address structure is optional. The sa
|
||||
* structure will contain a network interface name
|
||||
* on which the connection was
|
||||
* established, but we already know this. */
|
||||
|
||||
err=connect(sock,(struct sockaddr *)&sa,len);
|
||||
|
||||
if (err == 0){
|
||||
printf("Connect OK\n");
|
||||
}else{
|
||||
printf("Connect BAD, %i\n",err);
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************
|
||||
* process_con
|
||||
*
|
||||
* o Send and Receive data via socket
|
||||
* o Create a tx packet using x25api_t data type.
|
||||
* o Both the tx and rx packets contains 16 bytes headers
|
||||
* in front of the real data. It is the responsibility
|
||||
* of the applicatino to insert this 16 bytes on tx, and
|
||||
* remove the 16 bytes on rx.
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* o 16 byte Header: data structure:
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char qdm PACKED; Q/D/M bits
|
||||
* unsigned char cause PACKED; cause field
|
||||
* unsigned char diagn PACKED; diagnostics
|
||||
* unsigned char pktType PACKED;
|
||||
* unsigned short length PACKED;
|
||||
* unsigned char result PACKED;
|
||||
* unsigned short lcn PACKED;
|
||||
* char reserved[7] PACKED;
|
||||
* }x25api_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* x25api_hdr_t hdr PACKED;
|
||||
* char data[X25_MAX_DATA] PACKED;
|
||||
* }x25api_t;
|
||||
*
|
||||
* TX DATA:
|
||||
* --------
|
||||
* Each tx data packet must contain the above 16 byte header!
|
||||
*
|
||||
* Only relevant byte in the 16 byte tx header, is the
|
||||
* QDM byte. The driver will look at this byte to determine
|
||||
* if the Mbit (more data bit) should be set.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* RX DATA:
|
||||
* --------
|
||||
* Each rx data will contain the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte rx header, are the
|
||||
* LCN and QDM bytes.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* LCN = contains the lcn number for the rx frame.
|
||||
*
|
||||
* OOB DATA:
|
||||
* ---------
|
||||
* The OOB (out of band) data is used by the driver to
|
||||
* indicate x25 events for the active channel:
|
||||
* clear call, or restarts.
|
||||
*
|
||||
* Each OOB packet contains the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte oob header, are the
|
||||
* pktType, cause and diagn bytes.
|
||||
*
|
||||
* pktType = event type (ex Clear Call, Restart ...)
|
||||
* cause = x25 cause of the event
|
||||
* diagn = x25 diagnostic information used to determine
|
||||
* the cause of the event.
|
||||
*
|
||||
* Upon receiving an event, the sock should be considered
|
||||
* DEAD!!! Meaning it must be closed using the close()
|
||||
* function.
|
||||
*/
|
||||
|
||||
void process_con(void)
|
||||
{
|
||||
unsigned int Tx_count=0;
|
||||
unsigned short Tx_lgth,timeout=0;
|
||||
int err=0, i, Rx_count=0;
|
||||
struct timeval tv;
|
||||
x25api_t* api_tx_el;
|
||||
fd_set writeset,readset,oobset;
|
||||
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 5;
|
||||
Tx_lgth = MIN_FRM_LGTH;
|
||||
|
||||
api_tx_el = (x25api_t *)Tx_data;
|
||||
|
||||
memset(&api_tx_el->hdr,0,sizeof(x25api_hdr_t));
|
||||
|
||||
/* Fill in the packet data */
|
||||
for (i=0; i<Tx_lgth ; i++){
|
||||
api_tx_el->data[i] = (unsigned char) i;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_ZERO(&writeset);
|
||||
|
||||
FD_SET(sock,&readset);
|
||||
FD_SET(sock,&oobset);
|
||||
FD_SET(sock,&writeset);
|
||||
|
||||
/* This must be within the loop */
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = TIMEOUT;
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if already queued packet
|
||||
* cannot be sent
|
||||
*/
|
||||
|
||||
if((err=select(sock + 1,&readset, &writeset, &oobset, &tv))){
|
||||
|
||||
if (FD_ISSET(sock,&oobset)){
|
||||
|
||||
/* The OOB Message will indicate that an
|
||||
* asynchronous event occured. The applicaton
|
||||
* must stop everything and check the state of
|
||||
* the link. Since link might
|
||||
* have gone down */
|
||||
|
||||
/* In this example I just exit. A real
|
||||
* application would check the state of the
|
||||
* sock first by reading the header information.
|
||||
*/
|
||||
|
||||
/* If we fail to read the OOB message, we can
|
||||
* assume that the link is down. Thus, close
|
||||
* the socket and continue */
|
||||
|
||||
err = recv(sock, Rx_data, sizeof(Rx_data), MSG_OOB);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
|
||||
/* Link disconnected */
|
||||
printf("Failed to receive OOB %i\n", err);
|
||||
break;
|
||||
}else{
|
||||
api_tx_el = (x25api_t *)Rx_data;
|
||||
handle_oob_event(api_tx_el);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&readset)){
|
||||
|
||||
err = recv(sock, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
printf("Failed to rcv %i , %i\n", Rx_count, err);
|
||||
exit(1);
|
||||
}else{
|
||||
|
||||
/* Every received packet comes with the 16
|
||||
* bytes of header which driver adds on.
|
||||
* Header is structured as x25api_hdr_t.
|
||||
* (same as above)
|
||||
*/
|
||||
|
||||
|
||||
x25api_hdr_t *api_data =
|
||||
(x25api_hdr_t *)Rx_data;
|
||||
|
||||
if (api_data->qdm & 0x01){
|
||||
/* More bit is set, thus
|
||||
* handle it accordingly */
|
||||
}
|
||||
|
||||
printf("\tReceive OK, size: %i, qdm %x,"
|
||||
"cause %x, diagn %x, cnt: %i\n",
|
||||
err, api_data->qdm,
|
||||
api_data->cause,
|
||||
api_data->diagn, ++Rx_count);
|
||||
}
|
||||
|
||||
}
|
||||
if (FD_ISSET(sock,&writeset)){
|
||||
|
||||
err = send(sock, Tx_data, Tx_lgth +
|
||||
sizeof(x25api_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err > 0){
|
||||
printf("Packet Sent %i\n",
|
||||
++Tx_count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Stop after number of frames */
|
||||
if(Tx_count == NO_FRMS_TO_TX){
|
||||
|
||||
|
||||
x25api_t api_cmd;
|
||||
#if 0
|
||||
memset(&api_cmd, 0, sizeof(x25api_t));
|
||||
|
||||
sprintf(api_cmd.data,"nenad reset message");
|
||||
api_cmd.hdr.length = strlen(api_cmd.data);
|
||||
|
||||
if ((err=ioctl(sock,SIOC_WANPIPE_INTERRUPT,&api_cmd)) != 0){
|
||||
perror("Interrupt Ioctl");
|
||||
}
|
||||
|
||||
sleep(4);
|
||||
#endif
|
||||
memset(&api_cmd, 0, sizeof(x25api_t));
|
||||
api_cmd.hdr.cause=0x01;
|
||||
api_cmd.hdr.diagn=0x01;
|
||||
|
||||
if ((err=ioctl(sock,SIOC_WANPIPE_RESET_CALL,&api_cmd)) != 0){
|
||||
perror("Reset Ioctl");
|
||||
}
|
||||
sleep(4);
|
||||
break;
|
||||
}
|
||||
|
||||
timeout=0;
|
||||
}else{
|
||||
if (err == 0){
|
||||
if (++timeout == 5){
|
||||
printf("Sock timeout exceeded MAXIMUM\n");
|
||||
sleep(10);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
printf("Sock timeout try again !!!\n");
|
||||
}else{
|
||||
printf("Error in Select !!!\n");
|
||||
break;
|
||||
}
|
||||
}//if select
|
||||
}//for
|
||||
|
||||
close(sock);
|
||||
}
|
||||
|
||||
void handle_oob_event(x25api_t* api_hdr)
|
||||
{
|
||||
|
||||
switch (api_hdr->hdr.pktType){
|
||||
|
||||
case ASE_RESET_RQST:
|
||||
printf("SockId=%i : OOB : Rx Reset Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
/* NOTE: we don't have to close the socket,
|
||||
* since the reset doesn't clear the call
|
||||
* however, it means that there is something really
|
||||
* wrong and that data has been lost */
|
||||
return;
|
||||
|
||||
|
||||
case ASE_CLEAR_RQST:
|
||||
printf("SockId=%i : OOB : Rx Clear Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
|
||||
case ASE_RESTART_RQST:
|
||||
printf("SockId=%i : OOB : Rx Restart Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
case ASE_INTERRUPT:
|
||||
printf("SockId=%i : OOB : Rx Interrupt Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("SockId=%i : OOB : Rx Type=0x%02X : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.pktType,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,623 @@
|
|||
/*****************************************************************************
|
||||
* server_v1.c X25 API: SVC Server Application
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 server_v1.c utility will accept, user defined number, of
|
||||
* outgoing calls and tx/rx, user defined number, of packets on each
|
||||
* active svc.
|
||||
*
|
||||
* The server_v1 architecture is the classic mulit-process server,
|
||||
* that spawns a child process in order to handle incoming connections.
|
||||
*
|
||||
* IMPORTANT: For large number of LCN's, please refer to the P-Thread
|
||||
* server example pthread/ directory. The thread based
|
||||
* architecture model is a much more scalable solution.
|
||||
*
|
||||
* This utility should be used as an architectual model. It is up to
|
||||
* the user to handle all conditions of x25. Please refer to the
|
||||
* X25API programming manual for futher details.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_x25.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define MIN_FRM_LGTH 100
|
||||
#define MAX_FRM_LGTH 1400
|
||||
#define NO_FRMS_TO_TX 1000
|
||||
|
||||
#define MAX_X25_ADDR_SIZE 16
|
||||
#define MAX_X25_DATA_SIZE 129
|
||||
#define MAX_X25_FACL_SIZE 110
|
||||
|
||||
unsigned char Tx_data[MIN_FRM_LGTH + sizeof(x25api_hdr_t)];
|
||||
unsigned char Rx_data[1000];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection( char * );
|
||||
void process_con(int,int);
|
||||
void sig_chld (int sigio);
|
||||
void handle_oob_event(x25api_t* api_hdr, int sock);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call process_con() to transmit data
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 2){
|
||||
printf("Usage: ./server <card name>\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
signal(SIGCHLD,&sig_chld);
|
||||
|
||||
MakeConnection(argv[argc-1]);
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************
|
||||
* MakeConnection
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
*
|
||||
* IMPORTANT:
|
||||
* No signals are allowed in this part of the code.
|
||||
* Accept ioctl call, blocks and waits on a
|
||||
* signal which indicates that command is accepted.
|
||||
* If external signal tries to wake up the application
|
||||
* the accept ioctl call will wake up and fail the connection.
|
||||
*
|
||||
* This will be fixed in future releases.
|
||||
*/
|
||||
|
||||
int MakeConnection (char *i_name )
|
||||
{
|
||||
int err = 0;
|
||||
int sock, sock1;
|
||||
struct wan_sockaddr_ll sa;
|
||||
x25api_t api_cmd;
|
||||
fd_set oob,readset;
|
||||
|
||||
errno = 0;
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
|
||||
/* Create a new socket */
|
||||
sock = socket( AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( sock < 0 ) {
|
||||
perror("Socket");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Fill in binding information.
|
||||
* Before we use listen() system call
|
||||
* a socket must be binded into a virtual
|
||||
* network interface svc_listen.
|
||||
*
|
||||
* Card name must be supplied as well. In
|
||||
* this case the user supplies the name
|
||||
* eg: wanpipe1.
|
||||
*/
|
||||
sa.sll_family = AF_WANPIPE;
|
||||
sa.sll_protocol = htons(0x16);
|
||||
strcpy(sa.sll_device, "svc_listen");
|
||||
strcpy(sa.sll_card, i_name);
|
||||
|
||||
/* Bind a sock using the above address structure */
|
||||
if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) == -1){
|
||||
perror("bind");
|
||||
printf("Failed to bind socket to %s interface\n",i_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Put the sock into listening mode. Number 10 does not
|
||||
* mean anything, since number of connections is depended
|
||||
* on number of LCNs configured */
|
||||
|
||||
listen(sock,10);
|
||||
|
||||
|
||||
for (;;){
|
||||
|
||||
sock1=-1;
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&readset);
|
||||
FD_SET(sock,&oob);
|
||||
|
||||
|
||||
/* IMPORATAN: We use select() to wait for an incoming call
|
||||
* instead of just calling accept(), because the child
|
||||
* exit would trigger a CHILD signal which we will catch
|
||||
* in order to clear the process status, however this signal
|
||||
* would also wake up accept() system call. */
|
||||
|
||||
|
||||
if (select(sock+1,&readset,NULL,&oob,NULL) > 0){
|
||||
|
||||
if (FD_ISSET(sock,&oob)){
|
||||
printf("OOB Msg on listen Sock State %i !\n",
|
||||
ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0));
|
||||
|
||||
/* The X25 link went down or the driver is
|
||||
* in process of shutting down. Use listen()
|
||||
* to try to rebind to the x25 layer, and wait
|
||||
* until it comes up. If listen() fails the
|
||||
* driver is in shutdown process. */
|
||||
|
||||
/* Run listen() and try to rebind to the
|
||||
* driver */
|
||||
if (listen(sock,10) == 0){
|
||||
/* Listen successful: Listen socket will stay
|
||||
* connected to the x25 layer until it
|
||||
* comes back up. */
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("Listen closing on OOB: Sock State %i !\n",
|
||||
ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0));
|
||||
|
||||
/* Failed to listen(), the wanpipe
|
||||
* driver is shutting down. Thus
|
||||
* get out. */
|
||||
close(sock);
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock,&readset)){
|
||||
/* Accept call will block and wait for incoming calls.
|
||||
* When a call comes in, a new socket will be created
|
||||
* sock1. NOTE: that connection is not established yet.*/
|
||||
|
||||
sock1 = accept(sock,NULL,NULL);
|
||||
}
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sock1 < 0){
|
||||
printf ("Sock Accept Call Failed! %i\n",sock1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Reset the api command structure */
|
||||
memset(&api_cmd, 0, sizeof(x25api_t));
|
||||
|
||||
/* The GET CALL DATA ioctl call will write in the
|
||||
* incoming call data into api_cmd structure. Once
|
||||
* we have call data information, it is up to the
|
||||
* user to accept or clear call. */
|
||||
|
||||
if ((err=ioctl(sock1,SIOC_WANPIPE_GET_CALL_DATA,&api_cmd)) < 0){
|
||||
perror("GET CALL");
|
||||
printf ("Get Call Data Failed %i\n",err);
|
||||
close(sock1);
|
||||
continue;
|
||||
}else{
|
||||
printf("Call data: Lcn %i, Data %s\n",
|
||||
api_cmd.hdr.lcn,api_cmd.data);
|
||||
}
|
||||
|
||||
/* In this case, I accept all calls.
|
||||
* The ACCEPT CALL ioctl will acknowledge connecton */
|
||||
|
||||
/* The user can send data along with the call accept
|
||||
* indication, by submiting a filled in api_cmd
|
||||
* structure in the third field of the ioctl call. */
|
||||
|
||||
if ((err=ioctl(sock1,SIOC_WANPIPE_ACCEPT_CALL,0)) != 0){
|
||||
printf("Accept failed %i\n",err);
|
||||
close(sock1);
|
||||
continue;
|
||||
}else{
|
||||
printf("Accept OK %i\n",api_cmd.hdr.lcn);
|
||||
}
|
||||
|
||||
|
||||
/* If the call is accepted, fork a child to service
|
||||
* the call */
|
||||
|
||||
if (!fork()){
|
||||
close(sock);
|
||||
printf("CHILD Sock State %i CMD %i!\n",
|
||||
ioctl(sock1,SIOC_WANPIPE_SOCK_STATE,0),
|
||||
SIOC_WANPIPE_SOCK_STATE);
|
||||
process_con(sock1,api_cmd.hdr.lcn);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
close(sock1);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************
|
||||
* process_con
|
||||
*
|
||||
* o Send and Receive data via socket
|
||||
* o Create a tx packet using x25api_t data type.
|
||||
* o Both the tx and rx packets contains 16 bytes headers
|
||||
* in front of the real data. It is the responsibility
|
||||
* of the applicatino to insert this 16 bytes on tx, and
|
||||
* remove the 16 bytes on rx.
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* o 16 byte Header: data structure:
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char qdm PACKED; Q/D/M bits
|
||||
* unsigned char cause PACKED; cause field
|
||||
* unsigned char diagn PACKED; diagnostics
|
||||
* unsigned char pktType PACKED;
|
||||
* unsigned short length PACKED;
|
||||
* unsigned char result PACKED;
|
||||
* unsigned short lcn PACKED;
|
||||
* char reserved[7] PACKED;
|
||||
* }x25api_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* x25api_hdr_t hdr PACKED;
|
||||
* char data[X25_MAX_DATA] PACKED;
|
||||
* }x25api_t;
|
||||
*
|
||||
* TX DATA:
|
||||
* --------
|
||||
* Each tx data packet must contain the above 16 byte header!
|
||||
*
|
||||
* Only relevant byte in the 16 byte tx header, is the
|
||||
* QDM byte. The driver will look at this byte to determine
|
||||
* if the Mbit (more data bit) should be set.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* RX DATA:
|
||||
* --------
|
||||
* Each rx data will contain the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte rx header, are the
|
||||
* LCN and QDM bytes.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* LCN = contains the lcn number for the rx frame.
|
||||
*
|
||||
* OOB DATA:
|
||||
* ---------
|
||||
* The OOB (out of band) data is used by the driver to
|
||||
* indicate x25 events for the active channel:
|
||||
* clear call, or restarts.
|
||||
*
|
||||
* Each OOB packet contains the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte oob header, are the
|
||||
* pktType, cause and diagn bytes.
|
||||
*
|
||||
* pktType = event type (ex Clear Call, Restart ...)
|
||||
* cause = x25 cause of the event
|
||||
* diagn = x25 diagnostic information used to determine
|
||||
* the cause of the event.
|
||||
*
|
||||
* Upon receiving an event, the sock should be considered
|
||||
* DEAD!!! Meaning it must be closed using the close()
|
||||
* function.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void process_con(int sock1, int lcn)
|
||||
{
|
||||
unsigned int Tx_count=0, Rx_count=0;
|
||||
unsigned short Tx_lgth;
|
||||
x25api_t* api_tx_el;
|
||||
int err=0, i=0;
|
||||
fd_set writeset, readset, oobset;
|
||||
x25api_t api_cmd;
|
||||
|
||||
memset(&api_cmd, 0, sizeof(x25api_t));
|
||||
|
||||
/* Initialize the tx packet length */
|
||||
Tx_lgth = MIN_FRM_LGTH;
|
||||
|
||||
/* Cast the x25 16 byte header to the begining
|
||||
* of the tx packet. Using the pointer fill
|
||||
* in appropriate header information such as
|
||||
* QDM bits */
|
||||
api_tx_el = (x25api_t *)Tx_data;
|
||||
|
||||
/* Initialize the 16 byte tx header */
|
||||
memset(api_tx_el, 0, sizeof(x25api_hdr_t));
|
||||
|
||||
/* Set the Mbit (more bit)
|
||||
* currently this option is disabled */
|
||||
#ifdef _MORE_BIT_SET_
|
||||
api_tx_el->hdr.qdm = 0x01
|
||||
#endif
|
||||
|
||||
/* Fill in the tx packet data with arbitrary
|
||||
* information */
|
||||
for (i=0; i<Tx_lgth ; i++){
|
||||
api_tx_el->data[i] = (unsigned char) i;
|
||||
}
|
||||
|
||||
/* Start an infinite loop which will tx/rx data
|
||||
* over connected x25 svc's */
|
||||
for(;;) {
|
||||
FD_ZERO(&writeset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_ZERO(&readset);
|
||||
|
||||
//FD_SET(sock1,&writeset);
|
||||
FD_SET(sock1,&oobset);
|
||||
FD_SET(sock1,&readset);
|
||||
|
||||
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active x25 sockets.
|
||||
*
|
||||
* If the NONBLOCKING option has been used during connect()
|
||||
* the select will wait untill the channel is connected
|
||||
* (i.e. accept has been received). Once the channel is connected
|
||||
* the tx and rx will start. However, if the call is cleared for
|
||||
* any reason, the OOB message will indicate that event.
|
||||
*/
|
||||
|
||||
if(select(sock1 + 1, &readset, &writeset, &oobset, NULL)){
|
||||
|
||||
|
||||
if (FD_ISSET(sock1, &oobset)){
|
||||
|
||||
/* The OOB Message will indicate that an
|
||||
* asynchronous event occured. The applicaton
|
||||
* must stop everything and check the state of
|
||||
* the link. Since link might
|
||||
* have gone down */
|
||||
|
||||
/* In this example I just exit. A real
|
||||
* application would check the state of the
|
||||
* sock first by reading the header information.
|
||||
*/
|
||||
|
||||
/* IMPORTANT:
|
||||
* If we fail to read the OOB message, we can
|
||||
* assume that the link is down. Thus, close
|
||||
* the socket and continue !!! */
|
||||
|
||||
err = recv(sock1, Rx_data,
|
||||
sizeof(Rx_data), MSG_OOB);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
|
||||
/* SVC is disconnected */
|
||||
printf("Failed to read OOB %i , %i\n",
|
||||
Tx_count, err);
|
||||
break;
|
||||
}else{
|
||||
api_tx_el = (x25api_t *)Rx_data;
|
||||
handle_oob_event(api_tx_el,sock1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock1, &writeset)){
|
||||
|
||||
/* This socket is ready to tx */
|
||||
|
||||
/* The tx packet length contains the 16 byte
|
||||
* header. The tx packet was created above. */
|
||||
err = send(sock1, Tx_data,
|
||||
Tx_lgth+sizeof(x25api_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err > 0 ) {
|
||||
printf("Child LCN %i Packet Sent OK %i\n",
|
||||
lcn,++Tx_count);
|
||||
}
|
||||
/* If err<=0 it means that the send failed and that
|
||||
* driver is busy. Thus, the packet should be
|
||||
* requeued for re-transmission on the next
|
||||
* try !!!!
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock1, &readset)){
|
||||
|
||||
/* If there are pending rx packets
|
||||
* for a LISTEN socket, it means that
|
||||
* calls are pending. Thus, accept
|
||||
* a pending call */
|
||||
|
||||
err = recv(sock1, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
printf("Failed to rcv %i , %i\n",
|
||||
Rx_count, err);
|
||||
}else{
|
||||
x25api_hdr_t *api_data =
|
||||
(x25api_hdr_t *)Rx_data;
|
||||
|
||||
if (api_data->qdm & 0x01){
|
||||
/* More bit is set, thus
|
||||
* handle it accordingly */
|
||||
}
|
||||
|
||||
printf("\tReceive OK, size: %i, qdm %x,"
|
||||
" cause %x, diagn %x, cnt: %i\n",
|
||||
err, api_data->qdm,
|
||||
api_data->cause,
|
||||
api_data->diagn, ++Rx_count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Stop after number of frames */
|
||||
if(Tx_count == NO_FRMS_TO_TX){
|
||||
|
||||
/* Clear a call using CLEAR_CALL ioctl function.
|
||||
* User can send data along with the clear
|
||||
* indication by submitting x25api_t structure
|
||||
* in the third field of the ioctl call */
|
||||
memset(&api_cmd,0,sizeof(x25api_t));
|
||||
while(1){
|
||||
api_cmd.hdr.qdm = 0x80;
|
||||
if ((err=ioctl(sock1,SIOC_WANPIPE_CLEAR_CALL,&api_cmd)) == 0){
|
||||
printf("Clear Call OK sock %i\n",lcn);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ioctl(sock1,SIOC_WANPIPE_SOCK_STATE,0) == 1){
|
||||
/* Sock is disconnected */
|
||||
break;
|
||||
}
|
||||
usleep(100);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}//if select
|
||||
}//For
|
||||
|
||||
close(sock1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void sig_chld (int sigio)
|
||||
{
|
||||
pid_t pid;
|
||||
int stat;
|
||||
|
||||
while ((pid=waitpid(-1,&stat,WNOHANG)) > 0){
|
||||
printf("Child %d terminated\n",pid);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void handle_oob_event(x25api_t* api_hdr, int sock)
|
||||
{
|
||||
|
||||
switch (api_hdr->hdr.pktType){
|
||||
|
||||
case ASE_RESET_RQST:
|
||||
printf("SockId=%i : OOB : Rx Reset Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
/* NOTE: we don't have to close the socket,
|
||||
* since the reset doesn't clear the call
|
||||
* however, it means that there is something really
|
||||
* wrong and that data has been lost */
|
||||
return;
|
||||
|
||||
|
||||
case ASE_CLEAR_RQST:
|
||||
printf("SockId=%i : OOB : Rx Clear Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
|
||||
case ASE_RESTART_RQST:
|
||||
printf("SockId=%i : OOB : Rx Restart Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
case ASE_INTERRUPT:
|
||||
printf("SockId=%i : OOB : Rx Interrupt Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("SockId=%i : OOB : Rx Type=0x%02X : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
sock,
|
||||
api_hdr->hdr.pktType,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,782 @@
|
|||
/*****************************************************************************
|
||||
* server_v2.c X25 API: SVC Server Application
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 1995-2000 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 server.c utility will accept, user defined number, of
|
||||
* outgoing calls and tx/rx, user defined number, of packets on each
|
||||
* active svc.
|
||||
*
|
||||
* This utility should be used as an architectual model. It is up to
|
||||
* the user to handle all conditions of x25. Please refer to the
|
||||
* X25API programming manual for futher details.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <wait.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_x25.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
|
||||
#define TX_PACKET_LEN 128
|
||||
#define NO_FRMS_TO_TX 100
|
||||
#define MAX_RX_PKT_LEN 4096
|
||||
|
||||
#define MAX_X25_ADDR_SIZE 16
|
||||
#define MAX_X25_DATA_SIZE 129
|
||||
#define MAX_X25_FACL_SIZE 110
|
||||
|
||||
#define MAX_SOCK_NUM 255
|
||||
|
||||
#define TIMEOUT 10
|
||||
|
||||
#define NOWAIT_ON_CONNECT 1
|
||||
|
||||
#define CLEAR_NO_WAIT 0x00
|
||||
#define CLEAR_WAIT_FOR_DATA 0x80
|
||||
|
||||
#define LISTEN 0
|
||||
|
||||
|
||||
/* A single packet will be used to simulate tx data */
|
||||
unsigned char Tx_data[TX_PACKET_LEN + sizeof(x25api_hdr_t)];
|
||||
|
||||
/* A singel Rx buffer will be used to accept incoming
|
||||
* data. The buffer will be overwritten with each new
|
||||
* packet. */
|
||||
unsigned char Rx_data[MAX_RX_PKT_LEN];
|
||||
|
||||
|
||||
/* For each socket created, we will keep the
|
||||
* socket file descriptor and tx/rx pkt counts */
|
||||
typedef struct sock_api {
|
||||
int sock;
|
||||
int tx;
|
||||
int rx;
|
||||
}sock_api_t;
|
||||
|
||||
sock_api_t sock_fd[MAX_SOCK_NUM];
|
||||
|
||||
int max_sock_fd=0;
|
||||
|
||||
|
||||
|
||||
/*============================================================
|
||||
* Function Prototypes
|
||||
*===========================================================*/
|
||||
int MakeConnection( char * );
|
||||
void socket_event_handler( void);
|
||||
void setup_signal_handlers (void);
|
||||
void quit (int);
|
||||
void handle_oob_event(x25api_t* api_hdr, int sk_index);
|
||||
int issue_clear_call(int i, int opt);
|
||||
int CreateListenSock( char * );
|
||||
int accept_incoming_call(int sock);
|
||||
|
||||
|
||||
|
||||
|
||||
/* Defined global so it would only get allocated once.
|
||||
* If it was defined in MakeConnection() function it
|
||||
* would be allocated and dealocated every time we
|
||||
* run that function.
|
||||
*/
|
||||
x25api_t api_cmd;
|
||||
int con_max=MAX_SOCK_NUM;
|
||||
int tx_pkt=NO_FRMS_TO_TX;
|
||||
|
||||
#define APP_NAME "[server]"
|
||||
|
||||
void sig_chld (int sigio)
|
||||
{
|
||||
pid_t pid;
|
||||
int stat;
|
||||
|
||||
while ((pid=waitpid(-1,&stat,WNOHANG)) > 0){
|
||||
printf("Child %d terminated\n",pid);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*=============================================================
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call send_socket() to transmit data
|
||||
*
|
||||
*============================================================*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
pid_t pid;
|
||||
int stat;
|
||||
int i;
|
||||
|
||||
if (argc != 2){
|
||||
printf("Usage: ./wait_client <card name> \n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
signal(SIGCHLD,&sig_chld);
|
||||
|
||||
memset(sock_fd,0,sizeof(sock_fd));
|
||||
|
||||
sock_fd[LISTEN].sock = CreateListenSock(argv[argc-1]);
|
||||
|
||||
if (sock_fd[LISTEN].sock <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
max_sock_fd = sock_fd[LISTEN].sock;
|
||||
|
||||
socket_event_handler();
|
||||
|
||||
//Clean up
|
||||
for (i=0;i<MAX_SOCK_NUM;i++){
|
||||
if (sock_fd[i].sock){
|
||||
close(sock_fd[i].sock);
|
||||
}
|
||||
memset(&sock_fd[i],0,sizeof(sock_api_t));
|
||||
}
|
||||
|
||||
|
||||
/* Wait for the clear call children */
|
||||
while ((pid=waitpid(-1,&stat,WUNTRACED)) > 0){
|
||||
printf("Child %d terminated\n",pid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************
|
||||
* socket_event_handler
|
||||
*
|
||||
* o Send and Receive data via socket
|
||||
* o Create a tx packet using x25api_t data type.
|
||||
* o Both the tx and rx packets contains 16 bytes headers
|
||||
* in front of the real data. It is the responsibility
|
||||
* of the applicatino to insert this 16 bytes on tx, and
|
||||
* remove the 16 bytes on rx.
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* o 16 byte Header: data structure:
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char qdm PACKED; Q/D/M bits
|
||||
* unsigned char cause PACKED; cause field
|
||||
* unsigned char diagn PACKED; diagnostics
|
||||
* unsigned char pktType PACKED;
|
||||
* unsigned short length PACKED;
|
||||
* unsigned char result PACKED;
|
||||
* unsigned short lcn PACKED;
|
||||
* char reserved[7] PACKED;
|
||||
* }x25api_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* x25api_hdr_t hdr PACKED;
|
||||
* char data[X25_MAX_DATA] PACKED;
|
||||
* }x25api_t;
|
||||
*
|
||||
* TX DATA:
|
||||
* --------
|
||||
* Each tx data packet must contain the above 16 byte header!
|
||||
*
|
||||
* Only relevant byte in the 16 byte tx header, is the
|
||||
* QDM byte. The driver will look at this byte to determine
|
||||
* if the Mbit (more data bit) should be set.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* RX DATA:
|
||||
* --------
|
||||
* Each rx data will contain the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte rx header, are the
|
||||
* LCN and QDM bytes.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* LCN = contains the lcn number for the rx frame.
|
||||
*
|
||||
* OOB DATA:
|
||||
* ---------
|
||||
* The OOB (out of band) data is used by the driver to
|
||||
* indicate x25 events for the active channel:
|
||||
* clear call, or restarts.
|
||||
*
|
||||
* Each OOB packet contains the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte oob header, are the
|
||||
* pktType, cause and diagn bytes.
|
||||
*
|
||||
* pktType = event type (ex Clear Call, Restart ...)
|
||||
* cause = x25 cause of the event
|
||||
* diagn = x25 diagnostic information used to determine
|
||||
* the cause of the event.
|
||||
*
|
||||
* Upon receiving an event, the sock should be considered
|
||||
* DEAD!!! Meaning it must be closed using the close()
|
||||
* function.
|
||||
*/
|
||||
|
||||
void socket_event_handler(void)
|
||||
{
|
||||
unsigned short Tx_lgth,timeout=0;
|
||||
int err=0, i;
|
||||
struct timeval tv;
|
||||
x25api_t* api_tx_el;
|
||||
fd_set writeset,readset,oobset;
|
||||
|
||||
/* Setup a timeout value for the select statement, which is
|
||||
* going to block until the socket(s) are/is ready to tx/rx
|
||||
* or oob. In this case we will timeout afte 10 seconds of
|
||||
* inactivity */
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
|
||||
/* Initialize the tx packet length */
|
||||
Tx_lgth = TX_PACKET_LEN;
|
||||
|
||||
|
||||
/* Cast the x25 16 byte header to the begining
|
||||
* of the tx packet. Using the pointer fill
|
||||
* in appropriate header information such as
|
||||
* QDM bits */
|
||||
api_tx_el = (x25api_t *)Tx_data;
|
||||
|
||||
/* Initialize the 16 byte header */
|
||||
memset(api_tx_el, 0, sizeof(x25api_hdr_t));
|
||||
|
||||
/* Set the Mbit (more bit)
|
||||
* currently this option is disabled */
|
||||
#ifdef _MORE_BIT_SET_
|
||||
api_tx_el->hdr.qdm = 0x01
|
||||
#endif
|
||||
|
||||
/* Fill in the tx packet data with arbitrary
|
||||
* information */
|
||||
for (i=0; i<Tx_lgth ; i++){
|
||||
api_tx_el->data[i] = (unsigned char) i;
|
||||
}
|
||||
|
||||
|
||||
/* Start an infinite loop which will tx/rx data
|
||||
* over connected x25 svc's */
|
||||
|
||||
for(;;) {
|
||||
|
||||
/* Initialize select() flags */
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_ZERO(&writeset);
|
||||
|
||||
/* For all connected sockets, tell the select
|
||||
* what to wait for. Tx, Rx and OOB */
|
||||
for (i=0;i<con_max;i++){
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
FD_SET(sock_fd[i].sock,&readset);
|
||||
FD_SET(sock_fd[i].sock,&oobset);
|
||||
FD_SET(sock_fd[i].sock,&writeset);
|
||||
}
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active x25 sockets.
|
||||
*
|
||||
* If the NONBLOCKING option has been used during connect()
|
||||
* the select will wait untill the channel is connected
|
||||
* (i.e. accept has been received). Once the channel is connected
|
||||
* the tx and rx will start. However, if the call is cleared for
|
||||
* any reason, the OOB message will indicate that event.
|
||||
*/
|
||||
|
||||
if((err=select(max_sock_fd + 1,&readset, &writeset, &oobset, NULL /*&tv*/))){
|
||||
|
||||
/* One of the sockets returned OK for tx rx or oob
|
||||
* Thus, for all waiting connections, check each flag */
|
||||
|
||||
for (i=0;i<con_max;i++){
|
||||
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
|
||||
/* First check for OOB messages */
|
||||
|
||||
if (FD_ISSET(sock_fd[i].sock,&oobset)){
|
||||
|
||||
/* The OOB Message will indicate that an
|
||||
* asynchronous event occured. The applicaton
|
||||
* must stop everything and check the state of
|
||||
* the link. Since link might
|
||||
* have gone down */
|
||||
|
||||
/* In this example I just exit. A real
|
||||
* application would check the state of the
|
||||
* sock first by reading the header information.
|
||||
*/
|
||||
|
||||
/* IMPORTANT:
|
||||
* If we fail to read the OOB message, we can
|
||||
* assume that the link is down. Thus, close
|
||||
* the socket and continue !!! */
|
||||
|
||||
err = recv(sock_fd[i].sock, Rx_data, sizeof(Rx_data), MSG_OOB);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
|
||||
/* The state of the socket is disconnected.
|
||||
* We must close the socket and continue with
|
||||
* operation */
|
||||
printf("%s: SockId=%i : OOB Event : Disconnected\n",
|
||||
APP_NAME,sock_fd[i].sock);
|
||||
|
||||
if (i == LISTEN){
|
||||
/* If we received an OOB message
|
||||
* on listen socket, the x25 link
|
||||
* has gone down, due to lapb,
|
||||
* or physical layer.
|
||||
*
|
||||
* We can run liste() call to re-bind
|
||||
* to socket to the driver and wait
|
||||
* in select() for the x25 link to come
|
||||
* up.
|
||||
*
|
||||
* If listen() fails, the driver is being
|
||||
* shutdown and we must exit. */
|
||||
|
||||
if (listen(sock_fd[i].sock,0) == 0){
|
||||
/* Listen re-binded ok, thus
|
||||
* skip the section below */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memset(&api_cmd,0,sizeof(api_cmd));
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_GET_CALL_DATA,&api_cmd)) == 0){
|
||||
handle_oob_event(&api_cmd, i);
|
||||
}else{
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
|
||||
/* Do what ever you have to do to handle
|
||||
* this condiditon */
|
||||
}else{
|
||||
|
||||
/* OOB packet received OK ! */
|
||||
|
||||
api_tx_el = (x25api_t *)Rx_data;
|
||||
handle_oob_event(api_tx_el, i);
|
||||
}
|
||||
goto tx_rx_end;
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock_fd[i].sock,&readset)){
|
||||
|
||||
|
||||
/* If there are pending rx packets
|
||||
* for a LISTEN socket, it means that
|
||||
* calls are pending. Thus, accept
|
||||
* a pending call */
|
||||
if (i==LISTEN){
|
||||
accept_incoming_call(sock_fd[LISTEN].sock);
|
||||
|
||||
/* We should break, so we go back to select
|
||||
* thus, if there is another call to be accepted
|
||||
* it will have priority */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* This socket has received a packet. */
|
||||
|
||||
err = recv(sock_fd[i].sock, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
|
||||
/* This should never happen. Assume the channel
|
||||
* has been cleared. */
|
||||
printf("%s: Sockid=%i : Failed to rcv packet %i\n",
|
||||
APP_NAME,
|
||||
sock_fd[i].sock,
|
||||
err);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
|
||||
}else{
|
||||
|
||||
/* Packet received OK !
|
||||
*
|
||||
* Every received packet comes with the 16
|
||||
* bytes of header which driver adds on.
|
||||
* Header is structured as x25api_hdr_t.
|
||||
* (same as above)
|
||||
*/
|
||||
|
||||
x25api_hdr_t *api_data =
|
||||
(x25api_hdr_t *)Rx_data;
|
||||
|
||||
printf("%s: SockId=%i : RX : size=%i, qdm=0x%02X, cnt=%i\n",
|
||||
APP_NAME,
|
||||
sock_fd[i].sock,
|
||||
err,
|
||||
api_data->qdm,
|
||||
++sock_fd[i].rx);
|
||||
|
||||
if (api_data->qdm & 0x01){
|
||||
/* More bit is set, thus
|
||||
* handle it accordingly */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock_fd[i].sock,&writeset)){
|
||||
|
||||
/* This socket is ready to tx */
|
||||
|
||||
/* The tx packet length contains the 16 byte
|
||||
* header. The tx packet was created above. */
|
||||
err = send(sock_fd[i].sock, Tx_data,
|
||||
Tx_lgth + sizeof(x25api_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err>0){
|
||||
printf("%s: SockId=%i : TX : Cnt=%i\n",
|
||||
APP_NAME,
|
||||
sock_fd[i].sock,
|
||||
++sock_fd[i].tx);
|
||||
}
|
||||
|
||||
/* If err<=0 it means that the send failed and that
|
||||
* driver is busy. Thus, the packet should be
|
||||
* requeued for re-transmission on the next
|
||||
* try !!!!
|
||||
*/
|
||||
|
||||
|
||||
/* In this example I am clearing the connection
|
||||
* after I sent user specified number of packets */
|
||||
//if (sock_fd[i].tx >= tx_pkt){
|
||||
// issue_clear_call(i, CLEAR_WAIT_FOR_DATA);
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
tx_rx_end:
|
||||
for (i=0;i<con_max;i++){
|
||||
if (sock_fd[i].sock)
|
||||
break;
|
||||
}
|
||||
|
||||
/* All channels are down ! */
|
||||
if (i>=con_max)
|
||||
break;
|
||||
|
||||
}else{
|
||||
|
||||
/* select timeout occured. The svc could be
|
||||
* waiting for the accept, or there is something wrong
|
||||
* with the x25 configuration.
|
||||
*
|
||||
* It is up to the user to handle this condition
|
||||
* as they see fit */
|
||||
|
||||
if (err == 0){
|
||||
if (++timeout == 5){
|
||||
printf("Select() timeout exceeded MAXIMUM\n");
|
||||
break;
|
||||
}
|
||||
printf("Select() timeout try again !!!\n");
|
||||
}else{
|
||||
printf("Error in Select() !!!\n");
|
||||
break;
|
||||
}
|
||||
}//if select
|
||||
}//for
|
||||
|
||||
for (i=0;i<con_max;i++){
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
ioctl(sock_fd[i].sock,SIOC_WANPIPE_CLEAR_CALL,NULL);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handle_oob_event(x25api_t* api_hdr, int sk_index)
|
||||
{
|
||||
|
||||
switch (api_hdr->hdr.pktType){
|
||||
|
||||
case ASE_RESET_RQST:
|
||||
printf("%s: SockId=%i : OOB : Rx Reset Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
APP_NAME,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
/* NOTE: we don't have to close the socket,
|
||||
* since the reset doesn't clear the call
|
||||
* however, it means that there is something really
|
||||
* wrong and that data has been lost */
|
||||
return;
|
||||
|
||||
|
||||
case ASE_CLEAR_RQST:
|
||||
printf("%s: SockId=%i : OOB : Rx Clear Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
APP_NAME,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
|
||||
case ASE_RESTART_RQST:
|
||||
printf("%s: SockId=%i : OOB : Rx Restart Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
APP_NAME,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
case ASE_INTERRUPT:
|
||||
printf("%s: SockId=%i : OOB : Rx Interrupt Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
APP_NAME,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("%s: SockId=%i : OOB : Rx Type=0x%02X : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
APP_NAME,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.pktType,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
}
|
||||
close(sock_fd[sk_index].sock);
|
||||
sock_fd[sk_index].sock=0;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* issue_clear_call
|
||||
*
|
||||
* Input options (opt):
|
||||
* CLEAR_WAIT_FOR_DATA : Fail the clear call if data is
|
||||
* still pending the transmisstion.
|
||||
* This way tx data is not lost
|
||||
* due to the clear call.
|
||||
* CLEAR_NO_WAIT: Clear call regardless of current
|
||||
* pending data.
|
||||
*
|
||||
* NOTE: This function can block, which can cause buffer
|
||||
* overrun on other lcn's. Thus, it should be executed
|
||||
* in a separate process.
|
||||
*/
|
||||
|
||||
int issue_clear_call(int i, int opt)
|
||||
{
|
||||
volatile int err=0;
|
||||
|
||||
//FIXME: Fork is expensive use Pthread
|
||||
if (!fork()){
|
||||
memset(&api_cmd,0,sizeof(api_cmd));
|
||||
api_cmd.hdr.qdm=opt;
|
||||
for (;;){
|
||||
err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_CLEAR_CALL,&api_cmd);
|
||||
if (!err)
|
||||
break;
|
||||
|
||||
//printf("\t%s: SockId=%i: Clear Call Failed : Busy - Trying agin =%i!\n",
|
||||
// APP_NAME, sock_fd[i].sock,err);
|
||||
|
||||
/* If the state is disconnected, the call has been
|
||||
* cleared, thus break out */
|
||||
if (ioctl(sock_fd[i].sock,SIOC_WANPIPE_SOCK_STATE,0) == 1){
|
||||
break;
|
||||
}
|
||||
usleep(100);
|
||||
}
|
||||
printf("%s: SockId=%i: Call Cleared !\n",
|
||||
APP_NAME,
|
||||
sock_fd[i].sock);
|
||||
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}else{
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int accept_incoming_call(int sock)
|
||||
{
|
||||
int sock1=0;
|
||||
int err;
|
||||
int index=-1;
|
||||
|
||||
for (index=0; index < MAX_SOCK_NUM; index++){
|
||||
if (!sock_fd[index].sock)
|
||||
break;
|
||||
}
|
||||
|
||||
if (index >= MAX_SOCK_NUM){
|
||||
printf("%s: Maximum incoming SVCs reached!\n",APP_NAME);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sock1 = accept(sock,NULL,NULL);
|
||||
|
||||
if (sock1 <= 0){
|
||||
printf ("%s: Sock Accept call failed ! new sock=%i\n",APP_NAME,sock1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((err=ioctl(sock1,SIOC_WANPIPE_GET_CALL_DATA,&api_cmd)) != 0){
|
||||
printf("%s: Failed to get accept call data %i\n",APP_NAME,err);
|
||||
close(sock1);
|
||||
return -EINVAL;
|
||||
}else{
|
||||
api_cmd.data[api_cmd.hdr.length]=0;
|
||||
}
|
||||
|
||||
if ((err=ioctl(sock1,SIOC_WANPIPE_ACCEPT_CALL,0)) != 0){
|
||||
printf("%s: Accept call failed %i\n",APP_NAME,err);
|
||||
close(sock1);
|
||||
return -EINVAL;
|
||||
}else{
|
||||
printf("%s: Call Accept on LCN=%i\n",APP_NAME,api_cmd.hdr.lcn);
|
||||
}
|
||||
|
||||
sock_fd[index].sock = sock1;
|
||||
if (sock1 > max_sock_fd){
|
||||
max_sock_fd=sock1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************
|
||||
* CreateListenSock
|
||||
*
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
*/
|
||||
|
||||
int CreateListenSock (char *i_name )
|
||||
{
|
||||
int sock=0;
|
||||
struct wan_sockaddr_ll sa;
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
|
||||
/* Create a new socket */
|
||||
sock = socket( AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( sock < 0 ) {
|
||||
perror("Socket");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Fill in binding information
|
||||
* before we use connect() system call
|
||||
* a socket must be binded into a virtual
|
||||
* network interface svc_connect.
|
||||
*
|
||||
* Card name must be supplied as well. In
|
||||
* this case the user supplies the name
|
||||
* eg: wanpipe1.
|
||||
*/
|
||||
sa.sll_family = AF_WANPIPE;
|
||||
sa.sll_protocol = htons(X25_PROT);
|
||||
strcpy(sa.sll_device, "svc_listen");
|
||||
strcpy(sa.sll_card, i_name);
|
||||
|
||||
|
||||
/* Bind a sock using the above address structure */
|
||||
if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) == -1){
|
||||
perror("bind");
|
||||
printf("Failed to bind socket to %s interface\n",i_name);
|
||||
close(sock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (listen(sock,500) != 0){
|
||||
close(sock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,911 @@
|
|||
/*****************************************************************************
|
||||
* svc_client.c X25 API: SVC Client Application
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 call_place utility will establish, user defined number, of
|
||||
* outgoing calls and tx/rx, user defined number, of packets on each
|
||||
* active svc.
|
||||
*
|
||||
* This utility should be used as an architectual model. It is up to
|
||||
* the user to handle all conditions of x25. Please refer to the
|
||||
* X25API programming manual for futher details.
|
||||
*/
|
||||
|
||||
/*===========================================================
|
||||
* Header Files: Includes
|
||||
*==========================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <wait.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/sdla_x25.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* Defines
|
||||
*==========================================================*/
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define TX_PACKET_LEN 1428
|
||||
#define NO_FRMS_TO_TX 100
|
||||
#define MAX_RX_PKT_LEN 4096
|
||||
|
||||
#define MAX_X25_ADDR_SIZE 16
|
||||
#define MAX_X25_DATA_SIZE 129
|
||||
#define MAX_X25_FACL_SIZE 110
|
||||
|
||||
#define MAX_SOCK_NUM 255
|
||||
|
||||
#define TIMEOUT 10
|
||||
|
||||
#define NOWAIT_ON_CONNECT 1
|
||||
|
||||
#define CLEAR_NO_WAIT 0x00
|
||||
#define CLEAR_WAIT_FOR_DATA 0x80
|
||||
|
||||
#define APP_NAME "[svc_client]"
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* Global Variables
|
||||
*==========================================================*/
|
||||
|
||||
|
||||
/* A single packet will be used to simulate tx data */
|
||||
unsigned char Tx_data[TX_PACKET_LEN + sizeof(x25api_hdr_t)];
|
||||
|
||||
/* A singel Rx buffer will be used to accept incoming
|
||||
* data. The buffer will be overwritten with each new
|
||||
* packet. */
|
||||
unsigned char Rx_data[MAX_RX_PKT_LEN];
|
||||
|
||||
|
||||
/* For each socket created, we will keep the
|
||||
* socket file descriptor and tx/rx pkt counts */
|
||||
typedef struct sock_api {
|
||||
int sock;
|
||||
int tx;
|
||||
int rx;
|
||||
char clear;
|
||||
}sock_api_t;
|
||||
|
||||
sock_api_t sock_fd[MAX_SOCK_NUM];
|
||||
|
||||
int max_sock_fd=0;
|
||||
|
||||
int con_max=0;
|
||||
int tx_pkt=0;
|
||||
|
||||
|
||||
/* X25 tx/rx header structure. This structure will
|
||||
* be used to send commands down to the driver, as
|
||||
* well as read/insert header information from/into
|
||||
* rx and tx data respectively.
|
||||
*
|
||||
* Defined globaly so it would only get allocated once.
|
||||
*/
|
||||
|
||||
x25api_t api_cmd;
|
||||
|
||||
|
||||
|
||||
/*============================================================
|
||||
* Function Prototypes
|
||||
*===========================================================*/
|
||||
int MakeConnection( char * );
|
||||
void tx_rx_data( void);
|
||||
void setup_signal_handlers (void);
|
||||
void quit (int);
|
||||
int decode_oob_event(x25api_t* api_hdr, int sk_index);
|
||||
int issue_clear_call(int i);
|
||||
void sig_chld (int sigio);
|
||||
void sig_hnd (int sigio);
|
||||
int rx_data_act(int i);
|
||||
int tx_data_act(int i,int Tx_lgth);
|
||||
int handle_oob_event(int sk_index);
|
||||
|
||||
|
||||
|
||||
|
||||
/*=============================================================
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call tx_rx_data() to transmit/receive data
|
||||
*
|
||||
*============================================================*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
pid_t pid;
|
||||
int stat;
|
||||
int i;
|
||||
|
||||
if (argc != 4){
|
||||
printf("Usage: ./wait_client <card name> <num of calls> < num of packets to send> \n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
signal(SIGCHLD,&sig_chld);
|
||||
signal(SIGINT,&sig_hnd);
|
||||
signal(SIGTERM,&sig_hnd);
|
||||
con_max = atoi(argv[2]);
|
||||
tx_pkt = atoi(argv[3]);
|
||||
|
||||
memset(sock_fd,0,sizeof(sock_fd));
|
||||
|
||||
printf("\n%s: Attempting to establish %i calls, and tx %i packets \n",
|
||||
APP_NAME, con_max, tx_pkt);
|
||||
|
||||
proceed = MakeConnection(argv[1]);
|
||||
if (proceed == TRUE){
|
||||
|
||||
tx_rx_data();
|
||||
|
||||
/* Wait for the clear call children */
|
||||
while ((pid=waitpid(-1,&stat,WUNTRACED)) > 0){
|
||||
//printf("Child %d terminated\n",pid);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0;i<con_max;i++){
|
||||
if (!sock_fd[i].sock || sock_fd[i].clear)
|
||||
continue;
|
||||
|
||||
ioctl(sock_fd[i].sock,SIOC_WANPIPE_CLEAR_CALL,NULL);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
sock_fd[i].clear=1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* MakeConnection
|
||||
*
|
||||
* For user defined number of connections
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* o Setup x25 place call information
|
||||
* o Place call using connect()
|
||||
* o Read out the lcn used for that connection
|
||||
*==========================================================*/
|
||||
|
||||
int MakeConnection (char *i_name )
|
||||
{
|
||||
int len = sizeof(struct wan_sockaddr_ll);
|
||||
int err = 0;
|
||||
struct wan_sockaddr_ll sa;
|
||||
int i;
|
||||
|
||||
#ifdef NOWAIT_ON_CONNECT
|
||||
printf("%s: All sockets will use nonblocking call request!\n\n",APP_NAME);
|
||||
#endif
|
||||
|
||||
for (i=0; i<con_max; i++){
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
|
||||
/* Create a new socket */
|
||||
sock_fd[i].sock = socket( AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( sock_fd[i].sock < 0 ) {
|
||||
perror("Socket");
|
||||
sock_fd[i].sock=0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Fill in binding information
|
||||
* before we use connect() system call
|
||||
* a socket must be binded into a virtual
|
||||
* network interface svc_connect.
|
||||
*
|
||||
* Card name must be supplied as well. In
|
||||
* this case the user supplies the name
|
||||
* eg: wanpipe1.
|
||||
*/
|
||||
sa.sll_family = AF_WANPIPE;
|
||||
sa.sll_protocol = htons(X25_PROT);
|
||||
strcpy(sa.sll_device, "svc_connect");
|
||||
strcpy(sa.sll_card, i_name);
|
||||
|
||||
|
||||
/* Bind a sock using the above address structure */
|
||||
if(bind(sock_fd[i].sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) == -1){
|
||||
perror("bind");
|
||||
printf("Failed to bind socket to %s interface\n",i_name);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Reset the api command structure */
|
||||
memset(&api_cmd, 0, sizeof(x25api_t));
|
||||
|
||||
/* Write the call data into the command structure.
|
||||
* Note: -u data must be have even number of characters.
|
||||
* -f field cannot be set to zero (i.e. -f0)
|
||||
* Refer to x25.pdf hardware manual.
|
||||
*/
|
||||
sprintf(api_cmd.data,"-d1111 -s2222 -u1111");
|
||||
api_cmd.hdr.length = strlen(api_cmd.data);
|
||||
|
||||
/* Write the call data into a socket mail box using
|
||||
* the following ioctl call. This must be one before
|
||||
* the connect system call
|
||||
*/
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_SET_CALL_DATA,&api_cmd)) != 0){
|
||||
printf ("%s: Setting call data Failed!\n",APP_NAME);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* In some cases when placing multiple calls, this option
|
||||
* should be enabled to prevent the connect() call from
|
||||
* blocking and waiting for a response.
|
||||
*
|
||||
* By tunning SET NON_BLOCK ioctl call, the
|
||||
* connect() system call will not wait for the remote reply.
|
||||
*/
|
||||
#ifdef NOWAIT_ON_CONNECT
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_SET_NONBLOCK,0)) < 0){
|
||||
printf ("%s: Failed to setup socket for NON BLOCKING call request!",APP_NAME);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now we are ready to place a call. The address
|
||||
* structure is optional. The sa structure will contain
|
||||
* a network interface name on which the connection was
|
||||
* established
|
||||
*/
|
||||
if (connect(sock_fd[i].sock, (struct sockaddr *)&sa, len) != 0){
|
||||
perror("Connect: ");
|
||||
printf("%s: Failed to place call !\n",APP_NAME);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* In order to see what lcn we have established connection on,
|
||||
* run GET CALL DATA ioctl call, which will return the
|
||||
* appropriate information into api_cmd structure
|
||||
*/
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_GET_CALL_DATA,&api_cmd)) != 0){
|
||||
printf("%s: Failed to obtain call data!\n",APP_NAME);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
return FALSE;
|
||||
}else{
|
||||
printf("%s: Call Bounded to LCN %i\n",
|
||||
APP_NAME,api_cmd.hdr.lcn);
|
||||
}
|
||||
|
||||
/* Flush all pending print statements to screen */
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* At this point all the calls has been placed. If the connect() function
|
||||
* has been used in blocking mode, then we will wait in select() for
|
||||
* the accept calls to come in. Otherwise, the calls have been accepted,
|
||||
* and can proceed to tx and rx data. */
|
||||
|
||||
max_sock_fd=sock_fd[con_max-1].sock;
|
||||
printf("%s: Issued %i Calls\n",APP_NAME,con_max);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*=================================================================
|
||||
* TX_RX_DATA
|
||||
*
|
||||
* o Send and Receive data via socket
|
||||
* o Create a tx packet using x25api_t data type.
|
||||
* o Both the tx and rx packets contains 16 bytes headers
|
||||
* in front of the real data. It is the responsibility
|
||||
* of the applicatino to insert this 16 bytes on tx, and
|
||||
* remove the 16 bytes on rx.
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* o 16 byte Header: data structure:
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char qdm PACKED; Q/D/M bits
|
||||
* unsigned char cause PACKED; cause field
|
||||
* unsigned char diagn PACKED; diagnostics
|
||||
* unsigned char pktType PACKED;
|
||||
* unsigned short length PACKED;
|
||||
* unsigned char result PACKED;
|
||||
* unsigned short lcn PACKED;
|
||||
* char reserved[7] PACKED;
|
||||
* }x25api_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* x25api_hdr_t hdr PACKED;
|
||||
* char data[X25_MAX_DATA] PACKED;
|
||||
* }x25api_t;
|
||||
*
|
||||
* TX DATA:
|
||||
* --------
|
||||
* Each tx data packet must contain the above 16 byte header!
|
||||
*
|
||||
* Only relevant byte in the 16 byte tx header, is the
|
||||
* QDM byte. The driver will look at this byte to determine
|
||||
* if the Mbit (more data bit) should be set.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* RX DATA:
|
||||
* --------
|
||||
* Each rx data will contain the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte rx header, are the
|
||||
* LCN and QDM bytes.
|
||||
*
|
||||
* QDM: byte is a bit map of three bits:
|
||||
*
|
||||
* Q bit: Bit 2 : Qualifier bit, special kind of packet.
|
||||
* Can be used as control packet.
|
||||
* D bit: Bit 1 : Data acknolwedge bit. The remote will
|
||||
* acknowledge every packet sent.
|
||||
* M bit: Bit 0 : If your packet is greater than x25 MTU,
|
||||
* i.e 1024 bytes, than cut the packet to MTU size
|
||||
* and set the M bit to indicate more data.
|
||||
*
|
||||
* LCN = contains the lcn number for the rx frame.
|
||||
*
|
||||
* OOB DATA:
|
||||
* ---------
|
||||
* The OOB (out of band) data is used by the driver to
|
||||
* indicate x25 events for the active channel:
|
||||
* clear call, or restarts.
|
||||
*
|
||||
* Each OOB packet contains the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte oob header, are the
|
||||
* pktType, cause and diagn bytes.
|
||||
*
|
||||
* pktType = event type (ex Clear Call, Restart ...)
|
||||
* cause = x25 cause of the event
|
||||
* diagn = x25 diagnostic information used to determine
|
||||
* the cause of the event.
|
||||
*
|
||||
* Upon receiving an event, the sock should be considered
|
||||
* DEAD!!! Meaning it must be closed using the close()
|
||||
* function.
|
||||
*/
|
||||
|
||||
void tx_rx_data(void)
|
||||
{
|
||||
unsigned short Tx_lgth,timeout=0;
|
||||
int err=0, i;
|
||||
struct timeval tv;
|
||||
x25api_t* api_tx_el;
|
||||
fd_set writeset,readset,oobset;
|
||||
|
||||
/* Setup a timeout value for the select statement, which is
|
||||
* going to block until the socket(s) are/is ready to tx/rx
|
||||
* or oob. In this case we will timeout afte 10 seconds of
|
||||
* inactivity */
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
|
||||
/* Initialize the tx packet length */
|
||||
Tx_lgth = TX_PACKET_LEN;
|
||||
|
||||
|
||||
/* Cast the x25 16 byte header to the begining
|
||||
* of the tx packet. Using the pointer fill
|
||||
* in appropriate header information such as
|
||||
* QDM bits */
|
||||
api_tx_el = (x25api_t *)Tx_data;
|
||||
|
||||
/* Initialize the 16 byte header */
|
||||
memset(api_tx_el, 0, sizeof(x25api_hdr_t));
|
||||
|
||||
/* Set the Mbit (more bit)
|
||||
* currently this option is disabled */
|
||||
#ifdef MORE_BIT_SET
|
||||
api_tx_el->hdr.qdm = 0x01
|
||||
#endif
|
||||
|
||||
/* Fill in the tx packet data with arbitrary
|
||||
* information */
|
||||
for (i=0; i<Tx_lgth ; i++){
|
||||
api_tx_el->data[i] = (unsigned char) i;
|
||||
}
|
||||
|
||||
|
||||
/* Start an infinite loop which will tx/rx data
|
||||
* over connected x25 svc's */
|
||||
|
||||
for(;;) {
|
||||
|
||||
/* Initialize select() flags */
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_ZERO(&writeset);
|
||||
|
||||
/* For all connected sockets, tell the select
|
||||
* what to wait for. Tx, Rx and OOB */
|
||||
for (i=0;i<con_max;i++){
|
||||
if (!sock_fd[i].sock || sock_fd[i].clear)
|
||||
continue;
|
||||
|
||||
FD_SET(sock_fd[i].sock,&readset);
|
||||
FD_SET(sock_fd[i].sock,&oobset);
|
||||
FD_SET(sock_fd[i].sock,&writeset);
|
||||
}
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active x25 sockets.
|
||||
*
|
||||
* If the NONBLOCKING option has been used during connect()
|
||||
* the select will wait untill the channel is connected
|
||||
* (i.e. accept has been received). Once the channel is connected
|
||||
* the tx and rx will start. However, if the call is cleared for
|
||||
* any reason, the OOB message will indicate that event.
|
||||
*/
|
||||
|
||||
if((err=select(max_sock_fd + 1,&readset, &writeset, &oobset, NULL))){
|
||||
|
||||
/* One of the sockets returned OK for tx rx or oob
|
||||
* Thus, for all waiting connections, check each flag */
|
||||
|
||||
for (i=0;i<con_max;i++){
|
||||
|
||||
if (!sock_fd[i].sock || sock_fd[i].clear){
|
||||
continue;
|
||||
}
|
||||
|
||||
/* First check for OOB messages */
|
||||
if (FD_ISSET(sock_fd[i].sock,&oobset)){
|
||||
handle_oob_event(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock_fd[i].sock,&readset)){
|
||||
if (rx_data_act(i) != 0){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock_fd[i].sock,&writeset)){
|
||||
|
||||
int err=tx_data_act(i,Tx_lgth);
|
||||
|
||||
if (err==0){
|
||||
if (Tx_lgth == 1428){
|
||||
Tx_lgth=176;
|
||||
}else{
|
||||
Tx_lgth=1428;
|
||||
}
|
||||
}
|
||||
|
||||
/* In this example I am clearing the connection
|
||||
* after I sent user specified number of packets */
|
||||
if (sock_fd[i].tx >= tx_pkt){
|
||||
issue_clear_call(i);
|
||||
/* The parent process must close the sock
|
||||
* file handlers */
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
sock_fd[i].clear=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0;i<con_max;i++){
|
||||
if (sock_fd[i].sock)
|
||||
break;
|
||||
}
|
||||
|
||||
/* All channels are down ! */
|
||||
if (i>=con_max)
|
||||
break;
|
||||
|
||||
}else{
|
||||
|
||||
/* select timeout occured. The svc could be
|
||||
* waiting for the accept, or there is something wrong
|
||||
* with the x25 configuration.
|
||||
*
|
||||
* It is up to the user to handle this condition
|
||||
* as they see fit */
|
||||
|
||||
if (err == 0){
|
||||
if (++timeout == 5){
|
||||
printf("Select() timeout exceeded MAXIMUM\n");
|
||||
break;
|
||||
}
|
||||
printf("Select() timeout try again !!!\n");
|
||||
}else{
|
||||
printf("Error in Select() !!!\n");
|
||||
break;
|
||||
}
|
||||
}//if select
|
||||
}//for
|
||||
|
||||
for (i=0;i<con_max;i++){
|
||||
if (!sock_fd[i].sock || sock_fd[i].clear)
|
||||
continue;
|
||||
|
||||
ioctl(sock_fd[i].sock,SIOC_WANPIPE_CLEAR_CALL,NULL);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
sock_fd[i].clear=1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int tx_data_act(int i, int Tx_lgth)
|
||||
{
|
||||
int err=0;
|
||||
|
||||
/* This socket is ready to tx */
|
||||
|
||||
/* The tx packet length contains the 16 byte
|
||||
* header. The tx packet was created above. */
|
||||
err = send(sock_fd[i].sock, Tx_data,
|
||||
Tx_lgth + sizeof(x25api_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err>0){
|
||||
printf("%s: SockId=%i : TX : Cnt=%i\n",
|
||||
APP_NAME,
|
||||
sock_fd[i].sock,
|
||||
++sock_fd[i].tx);
|
||||
err=0;
|
||||
}else if (errno != EBUSY){
|
||||
perror("Send");
|
||||
err=1;
|
||||
}else{
|
||||
err=-1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* If err<=0 it means that the send failed and that
|
||||
* driver is busy. Thus, the packet should be
|
||||
* requeued for re-transmission on the next
|
||||
* try !!!!
|
||||
*/
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int rx_data_act(int i)
|
||||
{
|
||||
|
||||
int err;
|
||||
|
||||
/* This socket has received a packet. */
|
||||
|
||||
err = recv(sock_fd[i].sock, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
|
||||
/* This should never happen. However, check the sock state:
|
||||
* if we are still connected, proceed with normal operation.
|
||||
*/
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_SOCK_STATE,0)) == 0){
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%s: Sockid=%i : Failed to rcv packet %i\n",
|
||||
APP_NAME,
|
||||
sock_fd[i].sock,
|
||||
err);
|
||||
perror("Recv:");
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
return 1;
|
||||
|
||||
}else{
|
||||
|
||||
/* Packet received OK !
|
||||
*
|
||||
* Every received packet comes with the 16
|
||||
* bytes of header which driver adds on.
|
||||
* Header is structured as x25api_hdr_t.
|
||||
* (same as above)
|
||||
*/
|
||||
|
||||
x25api_hdr_t *api_data =
|
||||
(x25api_hdr_t *)Rx_data;
|
||||
|
||||
if (api_data->qdm & 0x01){
|
||||
/* More bit is set, thus
|
||||
* handle it accordingly */
|
||||
}
|
||||
|
||||
printf("%s: SockId=%i : RX : size=%i, qdm=0x%02X, cnt=%i\n",
|
||||
APP_NAME,
|
||||
sock_fd[i].sock,
|
||||
err,
|
||||
api_data->qdm,
|
||||
++sock_fd[i].rx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_oob_event(int i)
|
||||
{
|
||||
int err;
|
||||
x25api_t* api_tx_el;
|
||||
|
||||
/* The OOB Message will indicate that an
|
||||
* asynchronous event occured. The applicaton
|
||||
* must stop everything and check the state of
|
||||
* the link. Since link might
|
||||
* have gone down */
|
||||
|
||||
/* In this example I just exit. A real
|
||||
* application would check the state of the
|
||||
* sock first by reading the header information.
|
||||
*/
|
||||
|
||||
/* IMPORTANT:
|
||||
* If we fail to read the OOB message, we can
|
||||
* assume that the link is down. Thus, close
|
||||
* the socket and continue !!! */
|
||||
|
||||
err = recv(sock_fd[i].sock, Rx_data, sizeof(Rx_data), MSG_OOB);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err < 0){
|
||||
|
||||
/* The state of the socket is disconnected.
|
||||
* We must close the socket and continue with
|
||||
* operatio */
|
||||
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_SOCK_STATE,0)) == 0){
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%s: SockId=%i : OOB Event : State = %s\n",
|
||||
APP_NAME,sock_fd[i].sock,
|
||||
err == 1 ? "Disconnected" : "(Dis/Con)necting");
|
||||
|
||||
memset(&api_cmd,0,sizeof(api_cmd));
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_GET_CALL_DATA,&api_cmd)) == 0){
|
||||
if (decode_oob_event(&api_cmd, i) == 0){
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
}else{
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
|
||||
/* Do what ever you have to do to handle
|
||||
* this condiditon */
|
||||
}else{
|
||||
|
||||
/* OOB packet received OK ! */
|
||||
|
||||
api_tx_el = (x25api_t *)Rx_data;
|
||||
|
||||
printf("%s: SockId=%i : OOB : Packet type 0x%02X, Cause 0x%02X,"
|
||||
" Diagn 0x%02X, Result 0x%02X, Len %i, LCN %i\n",
|
||||
APP_NAME,
|
||||
sock_fd[i].sock,
|
||||
api_tx_el->hdr.pktType,
|
||||
api_tx_el->hdr.cause,
|
||||
api_tx_el->hdr.diagn,
|
||||
api_tx_el->hdr.result,
|
||||
api_tx_el->hdr.length,
|
||||
api_tx_el->hdr.lcn);
|
||||
|
||||
|
||||
if (decode_oob_event(api_tx_el, i) == 0){
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int decode_oob_event(x25api_t* api_hdr, int sk_index)
|
||||
{
|
||||
|
||||
switch (api_hdr->hdr.pktType){
|
||||
|
||||
case ASE_RESET_RQST:
|
||||
printf("%s: SockId=%i : OOB : Rx Reset Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
APP_NAME,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
/* NOTE: we don't have to close the socket,
|
||||
* since the reset doesn't clear the call
|
||||
* however, it means that there is something really
|
||||
* wrong and that data has been lost */
|
||||
return 1;
|
||||
|
||||
|
||||
case ASE_CLEAR_RQST:
|
||||
printf("%s: SockId=%i : OOB : Rx Clear Call : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
APP_NAME,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
|
||||
case ASE_RESTART_RQST:
|
||||
printf("%s: SockId=%i : OOB : Rx Restart Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
APP_NAME,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
case ASE_INTERRUPT:
|
||||
printf("%s: SockId=%i : OOB : Rx Interrupt Req : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
APP_NAME,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("%s: SockId=%i : OOB : Rx Type=0x%02X : Lcn=%i : diag=0x%02X : cause=0x%02X\n",
|
||||
APP_NAME,
|
||||
sock_fd[sk_index].sock,
|
||||
api_hdr->hdr.pktType,
|
||||
api_hdr->hdr.lcn,
|
||||
api_hdr->hdr.diagn,
|
||||
api_hdr->hdr.cause);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* issue_clear_call
|
||||
*
|
||||
* Input options (opt):
|
||||
* CLEAR_WAIT_FOR_DATA : Fail the clear call if data is
|
||||
* still pending the transmisstion.
|
||||
* This way tx data is not lost
|
||||
* due to the clear call.
|
||||
* CLEAR_NO_WAIT: Clear call regardless of current
|
||||
* pending data.
|
||||
*
|
||||
* NOTE: This function can block, which can cause buffer
|
||||
* overrun on other lcn's. Thus, it should be executed
|
||||
* in a separate process.
|
||||
*/
|
||||
|
||||
int issue_clear_call(int i)
|
||||
{
|
||||
volatile int err=0;
|
||||
|
||||
//FIXME: Fork is expensive use Pthread
|
||||
if (fork() == 0){
|
||||
|
||||
printf("\n%s: Issuing Clear Call: SockId=%i, Tx=%i, Pid=%i\n\n",
|
||||
APP_NAME, sock_fd[i].sock, sock_fd[i].tx, getpid());
|
||||
|
||||
while(ioctl(sock_fd[i].sock,SIOC_WANPIPE_CHECK_TX,NULL)){
|
||||
//printf("%s: Wait Count %i\n",prognamed,cnt);
|
||||
}
|
||||
|
||||
try_clear_again:
|
||||
printf("Clearing...\n");
|
||||
memset(&api_cmd,0,sizeof(api_cmd));
|
||||
api_cmd.hdr.cause=0x01;
|
||||
api_cmd.hdr.diagn=0x01;
|
||||
|
||||
/* Fast select implementation */
|
||||
sprintf(api_cmd.data,"-u1111");
|
||||
api_cmd.hdr.length = strlen(api_cmd.data);
|
||||
|
||||
err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_CLEAR_CALL,&api_cmd);
|
||||
if (err && err == EBUSY){
|
||||
perror("Ioctl Clear Call ");
|
||||
goto try_clear_again;
|
||||
}
|
||||
|
||||
printf("%s: SockId=%i: Call Cleared !\n",
|
||||
APP_NAME,
|
||||
sock_fd[i].sock);
|
||||
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
exit(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sig_chld (int sigio)
|
||||
{
|
||||
pid_t pid;
|
||||
int stat;
|
||||
|
||||
while ((pid=waitpid(-1,&stat,WNOHANG)) > 0){
|
||||
//printf("Child %d terminated\n",pid);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void sig_hnd (int sigio)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<con_max;i++){
|
||||
if (!sock_fd[i].sock || sock_fd[i].clear)
|
||||
continue;
|
||||
|
||||
ioctl(sock_fd[i].sock,SIOC_WANPIPE_CLEAR_CALL,NULL);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
sock_fd[i].clear=1;
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# ============================================================================
|
||||
# Makefile Make script for building Linux WAN router utilities.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 1995-1998 Sangoma Technologies Inc. All Rights Reserved.
|
||||
# ============================================================================
|
||||
|
||||
####### MACROS ###############################################################
|
||||
|
||||
# Build options.
|
||||
OS_TYPE = __LINUX__
|
||||
DEBUG = 2
|
||||
|
||||
# Project file paths.
|
||||
SYSINC = /usr/src/linux/include
|
||||
VPATH = $(SYSINC)
|
||||
|
||||
# Tools options.
|
||||
CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC)
|
||||
|
||||
####### RULES ################################################################
|
||||
|
||||
all: xdlc_api xdlc_mps
|
||||
@echo "Ok."
|
||||
|
||||
xdlc_api: xdlc_api.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
xdlc_mps: xdlc_mps.c ../lib/lib_api.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f xdlc_api
|
||||
rm -f xdlc_mps
|
|
@ -0,0 +1,97 @@
|
|||
XDLC API Package
|
||||
=================
|
||||
|
||||
Author: Nenad Corbic
|
||||
Date: Jul 2004
|
||||
|
||||
|
||||
|
||||
The xdlc api package contains the sample xdlc
|
||||
program that should be used in user application
|
||||
development.
|
||||
|
||||
|
||||
Contents of the API Package
|
||||
---------------------------
|
||||
|
||||
1) xdlc_api.c : This is a XDLC API applicationt that runs
|
||||
on top of a single xdlc interface. The
|
||||
interface can be Primary or Secondary.
|
||||
|
||||
Eg: Enable Rx and Tx: Tx 10 frames 100 bytes
|
||||
|
||||
./xdlc_api -i wp1sa1 -c wanpipe1 -r -w \
|
||||
-txsize 100 -txcnt 10 -verbose
|
||||
|
||||
|
||||
Eg: Enable Primary Rx Only
|
||||
|
||||
./xdlc_api -i wp1sa1 -c wanpipe1 -r -verbose
|
||||
|
||||
|
||||
|
||||
2) xdlc_mps.c : Multi Address XDLC Primary/Secondary Application.
|
||||
This app, supports multiple xdlc addresses as well
|
||||
as full duplex tx/rx.
|
||||
|
||||
Eg: Enable Secondary Rx and Tx: Tx 10 frames 100 bytes
|
||||
|
||||
./xdlc_mps -r -w -txsize 100 -txcnt 10 -verbose
|
||||
|
||||
Eg: Enable Primary Rx Only
|
||||
|
||||
./xdlc_mps -pri -r -verbose
|
||||
|
||||
|
||||
Note: ./xdlc_mps contains hardcoded intrace names.
|
||||
|
||||
Primary Interafces: wp1pa1 wp1pa2
|
||||
Secondary Interfaces: wp2sa1 wp2sa2
|
||||
|
||||
Please change these names to correspond
|
||||
to your interface names and re-make
|
||||
the application.
|
||||
|
||||
|
||||
XDLC API CALLS
|
||||
==============
|
||||
|
||||
SIOCS_XDLC_GET_CONF
|
||||
SIOCS_XDLC_SET_CONF
|
||||
|
||||
SIOCS_XDLC_START
|
||||
SIOCS_XDLC_STOP
|
||||
|
||||
SIOCS_XDLC_ENABLE_IFRAMES
|
||||
SIOCS_XDLC_DISABLE_IFRAMES
|
||||
|
||||
SIOCS_XDLC_CLEAR_POLL_TMR
|
||||
SIOCS_XDLC_FLUSH_TX_BUF
|
||||
|
||||
SIOCS_XDLC_GET_STATS
|
||||
SIOCS_XDLC_FLUSH_STATS
|
||||
|
||||
|
||||
XDLC OOB EXCEPTOINS
|
||||
===================
|
||||
EXCEP_LINK_CONNECTED
|
||||
EXCEP_LINK_CONNECTING,
|
||||
EXCEP_LINK_DISCONNECTED,
|
||||
EXCEP_LINK_DISCONNECTING,
|
||||
|
||||
EXCEP_OOB_EXCEPTIONS,
|
||||
|
||||
EXCEP_NO_RESPONSE_COUNTER,
|
||||
EXCEP_FRM_RETRANS_COUNTER,
|
||||
|
||||
EXCEP_RNR_COUNTER,
|
||||
EXCEP_SEC_NRM_TIMEOUT,
|
||||
|
||||
EXCEP_PRI_RD_FRAME_RECEIVED,
|
||||
EXCEP_FRM_DM_FRAME_RECEIVED,
|
||||
EXCEP_SEC_SNRM_FRAME_RECEIVED,
|
||||
EXCEP_SEC_DISC_FRAME_RECEIVED,
|
||||
|
||||
EXCEP_FRMR_FRAME_RECEIVED,
|
||||
EXCEP_FRMR_FRAME_TRANSMITTED
|
||||
|
|
@ -0,0 +1,501 @@
|
|||
/*****************************************************************************
|
||||
* xdlc_api.c XDLC API Sample Code
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/wanpipe_xdlc_iface.h>
|
||||
#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(wan_api_tx_hdr_t)];
|
||||
|
||||
/* Prototypes */
|
||||
int MakeConnection(void);
|
||||
void handle_socket( void);
|
||||
void sig_end(int sigid);
|
||||
void sig_tx(int sigid);
|
||||
|
||||
int sock;
|
||||
FILE *tx_fd=NULL,*rx_fd=NULL;
|
||||
|
||||
/***************************************************
|
||||
* 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;
|
||||
int err;
|
||||
wan_xdlc_conf_t xdlc_conf;
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
errno = 0;
|
||||
sock = socket(AF_WANPIPE, SOCK_RAW, 0);
|
||||
if( sock < 0 ) {
|
||||
perror("Socket");
|
||||
return -1;
|
||||
} /* if */
|
||||
|
||||
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);
|
||||
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);
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = ioctl(sock,WAN_DEVPRIV_SIOC(SIOCS_XDLC_GET_CONF), &xdlc_conf);
|
||||
if (err){
|
||||
perror("Get Address:");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 1
|
||||
printf("Inital Address 0x%X!\n",
|
||||
xdlc_conf.address);
|
||||
|
||||
xdlc_conf.address=33;
|
||||
|
||||
err = ioctl(sock,WAN_DEVPRIV_SIOC(SIOCS_XDLC_SET_CONF), &xdlc_conf);
|
||||
if (err){
|
||||
perror("Get Address:");
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = ioctl(sock,WAN_DEVPRIV_SIOC(SIOCS_XDLC_GET_CONF), &xdlc_conf);
|
||||
if (err){
|
||||
perror("Get Address:");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("New Address 0x%X!\n",
|
||||
xdlc_conf.address);
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (xdlc_conf.station == WANOPT_DTE){
|
||||
printf("Disabling I Frames\n");
|
||||
ioctl(sock,WAN_DEVPRIV_SIOC(SIOCS_XDLC_DISABLE_IFRAMES),NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
err = ioctl(sock,WAN_DEVPRIV_SIOC(SIOCS_XDLC_START),NULL);
|
||||
if (err){
|
||||
perror("XDLC Start: ");
|
||||
}else{
|
||||
printf("Address 0x%X started successfully!\n",
|
||||
xdlc_conf.address);
|
||||
}
|
||||
|
||||
printf("Socket bound to %s\n\n",if_name);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* HANDLE SOCKET
|
||||
*
|
||||
* o Read a socket
|
||||
* o Cast data received to wan_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 {
|
||||
* unsigned char error_flag;
|
||||
* unsigned short time_stamp;
|
||||
* unsigned char reserved[13];
|
||||
* } wan_api_rx_hdr_t;
|
||||
*
|
||||
* typedef struct {
|
||||
* wan_api_rx_hdr_t api_rx_hdr;
|
||||
* unsigned char data[1];
|
||||
* } api_rx_element_t;
|
||||
*
|
||||
*/
|
||||
|
||||
void handle_socket(void)
|
||||
{
|
||||
unsigned int Rx_count,Tx_count,Tx_length;
|
||||
wan_api_rx_element_t* api_rx_el;
|
||||
wan_api_tx_element_t * api_tx_el;
|
||||
fd_set ready,write,oob;
|
||||
int err,i;
|
||||
int rlen;
|
||||
|
||||
Rx_count = 0;
|
||||
Tx_count = 0;
|
||||
Tx_length = tx_size;
|
||||
|
||||
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(wan_api_tx_hdr_t));
|
||||
|
||||
/* If rx file is specified, open
|
||||
* it and prepare it for writing */
|
||||
if (files_used & RX_FILE_USED){
|
||||
rx_fd=fopen(rx_file,"wb");
|
||||
if (!rx_fd){
|
||||
printf("Failed to open file %s\n",rx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
printf("Opening %s rx file\n",rx_file);
|
||||
}
|
||||
|
||||
/* 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 = (wan_api_tx_element_t*)&Tx_data[0];
|
||||
|
||||
if (files_used & TX_FILE_USED){
|
||||
|
||||
/* TX file is used to transmit data */
|
||||
|
||||
tx_fd=fopen(tx_file,"rb");
|
||||
if (!tx_fd){
|
||||
printf("Failed to open file %s\n",tx_file);
|
||||
perror("File: ");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Opening %s tx file\n",rx_file);
|
||||
|
||||
rlen=fread((void*)&Tx_data[sizeof(wan_api_tx_hdr_t)],
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
if (!rlen){
|
||||
printf("%s: File empty!\n",
|
||||
tx_file);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
|
||||
/* Create a Tx packet based on user info, or
|
||||
* by deafult incrementing number starting from 0 */
|
||||
for (i=0;i<Tx_length;i++){
|
||||
if (tx_data == -1){
|
||||
api_tx_el->data[i] = (unsigned char)i;
|
||||
}else{
|
||||
api_tx_el->data[i] = (unsigned char)tx_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Main Rx Tx OOB routine */
|
||||
for(;;) {
|
||||
|
||||
/* Initialize all select() descriptors */
|
||||
FD_ZERO(&ready);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&oob);
|
||||
FD_SET(sock,&oob);
|
||||
FD_SET(sock,&ready);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock,&write);
|
||||
}
|
||||
|
||||
/* Select will block, until:
|
||||
* 1: OOB event, link level change
|
||||
* 2: Rx data available
|
||||
* 3: Interface able to Tx */
|
||||
|
||||
err=select(sock + 1,&ready, &write, &oob, NULL);
|
||||
|
||||
if (err < 0){
|
||||
/* Signal occured */
|
||||
continue;
|
||||
|
||||
}else if (err == 0){
|
||||
/* Timeout occured */
|
||||
continue;
|
||||
|
||||
}else if (err > 0){
|
||||
|
||||
fflush(stdout);
|
||||
if (FD_ISSET(sock,&oob)){
|
||||
|
||||
/* An OOB event is pending, usually indicating
|
||||
* a link level change */
|
||||
|
||||
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;
|
||||
}else{
|
||||
api_rx_el=(wan_api_rx_element_t*)&Rx_data[0];
|
||||
printf("Rx: OOB Excep: Addr=0x%X State=%s Exception=%s\n",
|
||||
api_rx_el->wan_rxapi_xdlc_address,
|
||||
XDLC_STATE_DECODE(api_rx_el->wan_rxapi_xdlc_state),
|
||||
XDLC_EXCEP_DECODE(api_rx_el->wan_rxapi_xdlc_exception));
|
||||
#if 0
|
||||
if (api_rx_el->wan_rxapi_xdlc_exception == EXCEP_SEC_SNRM_FRAME_RECEIVED){
|
||||
printf("Enabling I Frames\n");
|
||||
ioctl(sock,WAN_DEVPRIV_SIOC(SIOCS_XDLC_ENABLE_IFRAMES),NULL);
|
||||
#endif }
|
||||
|
||||
Tx_count=0;
|
||||
Rx_count=0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (FD_ISSET(sock,&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
|
||||
*/
|
||||
err = recv(sock, Rx_data, MAX_RX_DATA, 0);
|
||||
|
||||
if (!read_enable){
|
||||
goto bitstrm_skip_read;
|
||||
}
|
||||
|
||||
/* err indicates bytes received */
|
||||
if(err > 0) {
|
||||
|
||||
api_rx_el = (wan_api_rx_element_t*)&Rx_data[0];
|
||||
|
||||
/* Check the packet length */
|
||||
Rx_lgth = err - sizeof(wan_api_rx_hdr_t);
|
||||
if(Rx_lgth<=0) {
|
||||
printf("\nShort frame received (%d)\n",
|
||||
Rx_lgth);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((files_used & RX_FILE_USED) && rx_fd){
|
||||
fwrite((void*)&Rx_data[sizeof(wan_api_rx_hdr_t)],
|
||||
sizeof(char),
|
||||
Rx_lgth,
|
||||
rx_fd);
|
||||
}
|
||||
|
||||
++Rx_count;
|
||||
|
||||
if (verbose){
|
||||
printf("Received %i Olen=%i Length = %i\n",
|
||||
Rx_count, err,Rx_lgth);
|
||||
}else{
|
||||
//putchar('R');
|
||||
}
|
||||
|
||||
if (rx_cnt && rx_cnt < Rx_count){
|
||||
printf("User Re-Stopping\n");
|
||||
ioctl(sock,WAN_DEVPRIV_SIOC(SIOCS_XDLC_STOP),NULL);
|
||||
Rx_count=0;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("\nError receiving data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
bitstrm_skip_read:
|
||||
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock,&write)){
|
||||
|
||||
err = send(sock,Tx_data, Tx_length + sizeof(wan_api_tx_hdr_t), 0);
|
||||
|
||||
if (err <= 0){
|
||||
if (errno == EBUSY){
|
||||
if (verbose){
|
||||
printf("Sock busy try again!\n");
|
||||
}
|
||||
/* 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("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 ((files_used & TX_FILE_USED) && tx_fd){
|
||||
rlen=fread((void*)&Tx_data[sizeof(wan_api_tx_hdr_t)],
|
||||
sizeof(char),
|
||||
Tx_length,tx_fd);
|
||||
if (!rlen){
|
||||
printf("\nTx of file %s is done!\n",
|
||||
tx_file);
|
||||
break;
|
||||
}
|
||||
if (Tx_length != rlen){
|
||||
Tx_length = rlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_delay){
|
||||
usleep(tx_delay);
|
||||
}
|
||||
|
||||
if (tx_cnt && tx_size && Tx_count >= tx_cnt && !(files_used & TX_FILE_USED)){
|
||||
printf("Tx completed %i frames\n",Tx_count);
|
||||
write_enable=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
close (sock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call handle_socket() 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);
|
||||
signal(SIGTERM,&sig_end);
|
||||
signal(SIGUSR1,&sig_tx);
|
||||
|
||||
proceed = MakeConnection();
|
||||
if(proceed == 0){
|
||||
handle_socket();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
void sig_tx(int sigid)
|
||||
{
|
||||
printf("Sig write enable\n");
|
||||
write_enable=1;
|
||||
tx_cnt=1;
|
||||
}
|
||||
|
||||
void sig_end(int sigid)
|
||||
{
|
||||
|
||||
printf("Got Signal %i\n",sigid);
|
||||
|
||||
if (tx_fd){
|
||||
fclose(tx_fd);
|
||||
}
|
||||
if (rx_fd){
|
||||
fclose(rx_fd);
|
||||
}
|
||||
|
||||
ioctl(sock,WAN_DEVPRIV_SIOC(SIOCS_XDLC_STOP),NULL);
|
||||
|
||||
if (sock){
|
||||
close (sock);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,751 @@
|
|||
/*****************************************************************************
|
||||
* xdlc_mps.c XDLC API: Multi Pri/Sec Client Application
|
||||
*
|
||||
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 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.
|
||||
* ============================================================================
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
*/
|
||||
|
||||
/*===========================================================
|
||||
* Header Files: Includes
|
||||
*==========================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_wanpipe.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <wait.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#include <linux/wanpipe_xdlc_iface.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include "lib_api.h"
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* Defines
|
||||
*==========================================================*/
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
|
||||
#define TX_PACKET_LEN 1000
|
||||
#define MAX_RX_PKT_LEN 1000
|
||||
|
||||
#define MAX_XDLC_DATA_SIZE 100
|
||||
|
||||
#define MAX_SOCK_NUM 255
|
||||
|
||||
#define TIMEOUT 10
|
||||
|
||||
#define APP_NAME "xdlc_client"
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* Global Variables
|
||||
*==========================================================*/
|
||||
|
||||
|
||||
/* A single packet will be used to simulate tx data */
|
||||
unsigned char Tx_data[TX_PACKET_LEN];
|
||||
|
||||
/* A singel Rx buffer will be used to accept incoming
|
||||
* data. The buffer will be overwritten with each new
|
||||
* packet. */
|
||||
unsigned char Rx_data[MAX_RX_PKT_LEN];
|
||||
|
||||
|
||||
/* For each socket created, we will keep the
|
||||
* socket file descriptor and tx/rx pkt counts */
|
||||
typedef struct sock_api {
|
||||
int sock;
|
||||
int tx;
|
||||
int rx;
|
||||
int mtu;
|
||||
int mru;
|
||||
int address;
|
||||
wan_xdlc_conf_t cfg;
|
||||
}sock_api_t;
|
||||
|
||||
sock_api_t sock_fd[MAX_SOCK_NUM];
|
||||
|
||||
int max_sock_fd=0;
|
||||
|
||||
/* XDLC tx/rx header structure. This structure will
|
||||
* be used to send commands down to the driver, as
|
||||
* well as read/insert header information from/into
|
||||
* rx and tx data respectively.
|
||||
*
|
||||
* Defined globaly so it would only get allocated once.
|
||||
*/
|
||||
|
||||
unsigned char prognamed[100];
|
||||
|
||||
unsigned char *xdlc_dev_sec_map[]=
|
||||
{"wp2sa1", "wp2sa2", NULL};
|
||||
|
||||
unsigned char *xdlc_dev_pri_map[]=
|
||||
{"wp1pa1", "wp1pa2", NULL};
|
||||
|
||||
|
||||
int xdlc_devices=0;
|
||||
|
||||
/*============================================================
|
||||
Global Parameters
|
||||
*===========================================================*/
|
||||
|
||||
|
||||
|
||||
/*============================================================
|
||||
Function Prototypes
|
||||
*===========================================================*/
|
||||
int MakeConnection();
|
||||
void tx_rx_data( void);
|
||||
void setup_signal_handlers (void);
|
||||
void quit (int);
|
||||
void sig_chld (int sigio);
|
||||
void sig_hnd (int sigio);
|
||||
int rx_data_act(int i);
|
||||
int tx_data_act(int i,int Tx_lgth);
|
||||
int handle_oob_event(int sk_index);
|
||||
void close_connection(int i);
|
||||
int xdlc_get_numof_devices(void);
|
||||
|
||||
|
||||
/*=============================================================
|
||||
* Main:
|
||||
*
|
||||
* o Make a socket connection to the driver.
|
||||
* o Call tx_rx_data() to transmit/receive data
|
||||
*
|
||||
*============================================================*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int proceed;
|
||||
pid_t pid;
|
||||
int stat;
|
||||
int i;
|
||||
|
||||
xdlc_devices=xdlc_get_numof_devices();
|
||||
|
||||
sprintf(prognamed,"%s[%i]",APP_NAME,getpid());
|
||||
|
||||
i_cnt=1;
|
||||
card_cnt=1;
|
||||
if (init_args(argc,argv) == 0){
|
||||
usage(argv[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
signal(SIGCHLD,&sig_chld);
|
||||
signal(SIGINT,&sig_hnd);
|
||||
signal(SIGTERM,&sig_hnd);
|
||||
|
||||
memset(sock_fd,0,sizeof(sock_fd));
|
||||
|
||||
printf("\n%s: Attempting to establish %i connections, and tx %i (%i bytes) packets \n",
|
||||
prognamed, xdlc_devices, tx_cnt, tx_size);
|
||||
|
||||
proceed = MakeConnection();
|
||||
if (proceed == TRUE){
|
||||
|
||||
tx_rx_data();
|
||||
|
||||
/* Wait for the clear call children */
|
||||
while ((pid=waitpid(-1,&stat,WUNTRACED)) > 0){
|
||||
//printf("Child %d terminated\n",pid);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0;i<xdlc_devices;i++){
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
/*===========================================================
|
||||
* MakeConnection
|
||||
*
|
||||
* For user defined number of connections
|
||||
* o Create a Socket
|
||||
* o Bind a socket to a wanpipe network interface
|
||||
* o Setup x25 place call information
|
||||
* o Place call using connect()
|
||||
* o Read out the lcn used for that connection
|
||||
*==========================================================*/
|
||||
|
||||
int MakeConnection (void)
|
||||
{
|
||||
int err = 0;
|
||||
struct wan_sockaddr_ll sa;
|
||||
int i;
|
||||
int connected_devices=0;
|
||||
|
||||
|
||||
for (i=0; i<xdlc_devices; i++){
|
||||
|
||||
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
|
||||
|
||||
/* Create a new socket */
|
||||
sock_fd[i].sock = socket( AF_WANPIPE, SOCK_RAW, AF_WANPIPE);
|
||||
if( sock_fd[i].sock < 0 ) {
|
||||
perror("Socket: ");
|
||||
sock_fd[i].sock=0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Fill in binding information
|
||||
* before we use connect() system call
|
||||
* a socket must be binded into a virtual
|
||||
* network interface svc_connect.
|
||||
*
|
||||
* Card name must be supplied as well. In
|
||||
* this case the user supplies the name
|
||||
* eg: wanpipe1.
|
||||
*/
|
||||
sa.sll_family = AF_WANPIPE;
|
||||
sa.sll_protocol = htons(PVC_PROT);
|
||||
if (primary_enable){
|
||||
strcpy(sa.sll_device, xdlc_dev_pri_map[i]);
|
||||
}else{
|
||||
strcpy(sa.sll_device, xdlc_dev_sec_map[i]);
|
||||
}
|
||||
strcpy(sa.sll_card, "wanpipe1");
|
||||
|
||||
|
||||
/* Bind a sock using the above address structure */
|
||||
if(bind(sock_fd[i].sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) == -1){
|
||||
perror("Bind: ");
|
||||
printf("Failed to bind socket to %s interface\n",sa.sll_device);
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
continue;
|
||||
}
|
||||
|
||||
err = ioctl(sock_fd[i].sock,
|
||||
WAN_DEVPRIV_SIOC(SIOCS_XDLC_GET_CONF),
|
||||
&sock_fd[i].cfg);
|
||||
if (err){
|
||||
perror("Get Address:");
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
continue;
|
||||
}
|
||||
|
||||
err = ioctl(sock_fd[i].sock,
|
||||
WAN_DEVPRIV_SIOC(SIOCS_XDLC_START),
|
||||
NULL);
|
||||
if (err){
|
||||
perror("XDLC Start: ");
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
continue;
|
||||
|
||||
}else{
|
||||
printf("Address 0x%X started successfully!\n",
|
||||
sock_fd[i].cfg.address);
|
||||
}
|
||||
|
||||
sock_fd[i].mtu=128;
|
||||
sock_fd[i].mru=128;
|
||||
|
||||
connected_devices++;
|
||||
|
||||
if (sock_fd[i].sock > max_sock_fd){
|
||||
max_sock_fd=sock_fd[i].sock;
|
||||
}
|
||||
|
||||
/* Flush all pending print statements to screen */
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* At this point all the calls has been placed. If the connect() function
|
||||
* has been used in blocking mode, then we will wait in select() for
|
||||
* the accept calls to come in. Otherwise, the calls have been accepted,
|
||||
* and can proceed to tx and rx data. */
|
||||
|
||||
printf("%s: Connected to %i %s devices! (Requested %i)\n\n\n",
|
||||
prognamed,connected_devices,
|
||||
primary_enable?"PRI":"SEC",
|
||||
xdlc_devices);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*=================================================================
|
||||
* TX_RX_DATA
|
||||
*
|
||||
* o Send and Receive data via socket
|
||||
* o Create a tx packet using x25api_t data type.
|
||||
* o Both the tx and rx packets contains 16 bytes headers
|
||||
* in front of the real data. It is the responsibility
|
||||
* of the applicatino to insert this 16 bytes on tx, and
|
||||
* remove the 16 bytes on rx.
|
||||
*
|
||||
* ------------------------------------------
|
||||
* | 16 bytes | X bytes ...
|
||||
* ------------------------------------------
|
||||
* Header Data
|
||||
*
|
||||
* o 16 byte Header: data structure:
|
||||
*
|
||||
* typedef struct {
|
||||
* union {
|
||||
* struct {
|
||||
* unsigned char state;
|
||||
* unsigned char address;
|
||||
* unsigned short exception;
|
||||
* }xdlc;
|
||||
* unsigned char reserved[16];
|
||||
* }u;
|
||||
*
|
||||
* #define wan_hdr_xdlc_state u.xdlc.state
|
||||
* #define wan_hdr_xdlc_address u.xdlc.address
|
||||
* #define wan_hdr_xdlc_exception u.xdlc.exception
|
||||
* } wan_api_rx_hdr_t;
|
||||
*
|
||||
*
|
||||
* typedef struct {
|
||||
* wan_api_rx_hdr_t api_rx_hdr;
|
||||
* unsigned char data[0];
|
||||
* #define wan_rxapi_xdlc_state api_rx_hdr.wan_hdr_xdlc_state
|
||||
* #define wan_rxapi_xdlc_address api_rx_hdr.wan_hdr_xdlc_address
|
||||
* #define wan_rxapi_xdlc_exception api_rx_hdr.wan_hdr_xdlc_exception
|
||||
* } wan_api_rx_element_t;
|
||||
*
|
||||
*
|
||||
* TX DATA:
|
||||
* --------
|
||||
* Each tx data packet must contain the above 16 byte header!
|
||||
*
|
||||
* There are no relevant bytes at this time.
|
||||
* Set the tx header to ZERO.
|
||||
*
|
||||
* RX DATA:
|
||||
* --------
|
||||
* Each rx data will contain the above 16 byte header!
|
||||
*
|
||||
* There are no relevant bytes at this time.
|
||||
* Set the tx header to ZERO.
|
||||
*
|
||||
* OOB DATA:
|
||||
* ---------
|
||||
* The OOB (out of band) data is used by the driver to
|
||||
* indicate Xdlc events for the active channel:
|
||||
*
|
||||
* Each OOB packet contains the above 16 byte header!
|
||||
*
|
||||
* Relevant bytes in the 16 byte oob header, are:
|
||||
*
|
||||
*
|
||||
* state : State of the xdlc device
|
||||
*
|
||||
* address : Address of the xdlc device
|
||||
*
|
||||
* exception: Exception on the xdlc device
|
||||
*
|
||||
* The socket will be available after ALL OOB messages.
|
||||
* It is up the the user to identify when the
|
||||
* Xdlc connection has been terminated.
|
||||
*/
|
||||
|
||||
void tx_rx_data(void)
|
||||
{
|
||||
int err=0, i;
|
||||
struct timeval tv;
|
||||
wan_api_tx_element_t* api_tx_el;
|
||||
fd_set writeset,readset,oobset;
|
||||
|
||||
/* Setup a timeout value for the select statement, which is
|
||||
* going to block until the socket(s) are/is ready to tx/rx
|
||||
* or oob. In this case we will timeout afte 10 seconds of
|
||||
* inactivity */
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
|
||||
|
||||
/* Cast the x25 16 byte header to the begining
|
||||
* of the tx packet. Using the pointer fill
|
||||
* in appropriate header information such as
|
||||
* QDM bits */
|
||||
api_tx_el = (wan_api_tx_element_t *)Tx_data;
|
||||
|
||||
/* Initialize the 16 byte header */
|
||||
memset(api_tx_el, 0, sizeof(wan_api_rx_hdr_t));
|
||||
|
||||
/* Fill in the tx packet data with arbitrary
|
||||
* information */
|
||||
for (i=0; i<tx_size; i++){
|
||||
api_tx_el->data[i] = (unsigned char) i;
|
||||
}
|
||||
|
||||
/* Start an infinite loop which will tx/rx data
|
||||
* over connected x25 svc's */
|
||||
|
||||
for(;;) {
|
||||
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
|
||||
/* Initialize select() flags */
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&oobset);
|
||||
FD_ZERO(&writeset);
|
||||
|
||||
/* For all connected sockets, tell the select
|
||||
* what to wait for. Tx, Rx and OOB */
|
||||
for (i=0;i<xdlc_devices;i++){
|
||||
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
FD_SET(sock_fd[i].sock,&readset);
|
||||
FD_SET(sock_fd[i].sock,&oobset);
|
||||
|
||||
if (write_enable){
|
||||
FD_SET(sock_fd[i].sock,&writeset);
|
||||
}
|
||||
}
|
||||
|
||||
/* The select function must be used to implement flow control.
|
||||
* WANPIPE socket will block the user if the socket cannot send
|
||||
* or there is nothing to receive.
|
||||
*
|
||||
* By using the last socket file descriptor +1 select will wait
|
||||
* for all active xdlc sockets.
|
||||
*/
|
||||
|
||||
err=select(max_sock_fd + 1,&readset, &writeset, &oobset, &tv);
|
||||
|
||||
if (err < 0){
|
||||
|
||||
/* Signal Interruption */
|
||||
continue;
|
||||
|
||||
}else if (err == 0){
|
||||
|
||||
/* timeout */
|
||||
continue;
|
||||
|
||||
}else if (err > 0) {
|
||||
|
||||
/* One of the sockets returned OK for tx rx or oob
|
||||
* Thus, for all waiting connections, check each flag */
|
||||
|
||||
for (i=0;i<xdlc_devices;i++){
|
||||
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
/* First check for OOB messages */
|
||||
if (FD_ISSET(sock_fd[i].sock,&oobset)){
|
||||
if (handle_oob_event(i)){
|
||||
close_connection(i);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock_fd[i].sock,&readset)){
|
||||
if (rx_data_act(i)){
|
||||
close_connection(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock_fd[i].sock,&writeset)){
|
||||
|
||||
tx_data_act(i,tx_size);
|
||||
|
||||
/* In this example I am clearing the connection
|
||||
* after I sent user specified number of packets */
|
||||
if (tx_delay)
|
||||
sleep(tx_delay);
|
||||
|
||||
if (sock_fd[i].tx >= tx_cnt){
|
||||
write_enable=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}//if select
|
||||
}//for
|
||||
|
||||
for (i=0;i<xdlc_devices;i++){
|
||||
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
close_connection(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int tx_data_act(int i, int Tx_lgth)
|
||||
{
|
||||
int err;
|
||||
/* This socket is ready to tx */
|
||||
#if 0
|
||||
if (Tx_lgth > sock_fd[i].mtu){
|
||||
printf("%s: Tx warning: Tx length %i > MTU %i, using MTU!\n",
|
||||
prognamed,Tx_lgth,sock_fd[i].mtu);
|
||||
Tx_lgth=sock_fd[i].mtu;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The tx packet length contains the 16 byte
|
||||
* header. The tx packet was created above. */
|
||||
err = send(sock_fd[i].sock, Tx_data,
|
||||
Tx_lgth + sizeof(wan_api_tx_hdr_t), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err>0){
|
||||
++sock_fd[i].tx;
|
||||
if (verbose){
|
||||
printf("%s: SockId=%i : TX : size=%i, cnt=%i\n",
|
||||
prognamed,
|
||||
sock_fd[i].sock,
|
||||
Tx_lgth,
|
||||
sock_fd[i].tx);
|
||||
}
|
||||
}else{
|
||||
if (errno != EBUSY){
|
||||
perror("Send");
|
||||
}
|
||||
}
|
||||
|
||||
/* If err<=0 it means that the send failed and that
|
||||
* driver is busy. Thus, the packet should be
|
||||
* requeued for re-transmission on the next
|
||||
* try !!!!
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int rx_data_act(int i)
|
||||
{
|
||||
|
||||
int err;
|
||||
|
||||
/* This socket has received a packet. */
|
||||
|
||||
err = recv(sock_fd[i].sock, Rx_data, sizeof(Rx_data), 0);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if(err < 0 ) {
|
||||
|
||||
perror("Recv");
|
||||
|
||||
/* This should never happen. However, check the sock state:
|
||||
* if we are still connected, proceed with normal operation.
|
||||
*/
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_SOCK_STATE,0)) == 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("%s: Sockid=%i : Failed to rcv packet %i\n",
|
||||
prognamed,
|
||||
sock_fd[i].sock,
|
||||
err);
|
||||
return 1;
|
||||
|
||||
}else{
|
||||
|
||||
/* Packet received OK !
|
||||
*
|
||||
* Every received packet comes with the 16
|
||||
* bytes of header which driver adds on.
|
||||
* Header is structured as x25api_hdr_t.
|
||||
* (same as above)
|
||||
*/
|
||||
|
||||
if (!read_enable){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
err-=sizeof(wan_api_rx_hdr_t);
|
||||
|
||||
if (err > sock_fd[i].mru){
|
||||
/* This should never happen, sanity check */
|
||||
printf("%s: Rx warning: Rx len %i > MRU %i\n",
|
||||
prognamed,
|
||||
err,sock_fd[i].mru);
|
||||
}
|
||||
|
||||
++sock_fd[i].rx;
|
||||
|
||||
if (verbose){
|
||||
printf("%s: SockId=%i : RX : size=%i, cnt=%i\n",
|
||||
prognamed,
|
||||
sock_fd[i].sock,
|
||||
err,
|
||||
sock_fd[i].rx);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_oob_event(int i)
|
||||
{
|
||||
int err;
|
||||
wan_api_rx_element_t* api_rx_el;
|
||||
|
||||
/* The OOB Message will indicate that an
|
||||
* asynchronous event occured. The applicaton
|
||||
* must stop everything and check the state of
|
||||
* the link. Since link might
|
||||
* have gone down */
|
||||
|
||||
/* In this example I just exit. A real
|
||||
* application would check the state of the
|
||||
* sock first by reading the header information.
|
||||
*/
|
||||
|
||||
/* IMPORTANT:
|
||||
* If we fail to read the OOB message, we can
|
||||
* assume that the link is down. Thus, close
|
||||
* the socket and continue !!! */
|
||||
|
||||
err = recv(sock_fd[i].sock, Rx_data, sizeof(Rx_data), MSG_OOB);
|
||||
|
||||
/* err contains number of bytes transmited */
|
||||
if (err < 0){
|
||||
|
||||
/* The state of the socket is disconnected.
|
||||
* We must close the socket and continue with
|
||||
* operatio */
|
||||
|
||||
if ((err=ioctl(sock_fd[i].sock,SIOC_WANPIPE_SOCK_STATE,0)) == 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("%s: SockId=%i : OOB Event : State = %s\n",
|
||||
prognamed,sock_fd[i].sock,
|
||||
err == 1 ? "Disconnected" : "(Dis/Con)necting");
|
||||
|
||||
return 1;
|
||||
|
||||
/* Do what ever you have to do to handle
|
||||
* this condiditon */
|
||||
}else{
|
||||
|
||||
/* OOB packet received OK ! */
|
||||
|
||||
api_rx_el = (wan_api_rx_element_t *)Rx_data;
|
||||
|
||||
printf("Rx: OOB Excep: Addr=0x%X State=%s Exception=%s\n",
|
||||
api_rx_el->wan_rxapi_xdlc_address,
|
||||
XDLC_STATE_DECODE(api_rx_el->wan_rxapi_xdlc_state),
|
||||
XDLC_EXCEP_DECODE(api_rx_el->wan_rxapi_xdlc_exception));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void sig_chld (int sigio)
|
||||
{
|
||||
pid_t pid;
|
||||
int stat;
|
||||
|
||||
while ((pid=waitpid(-1,&stat,WNOHANG)) > 0){
|
||||
//printf("Child %d terminated\n",pid);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void sig_hnd (int sigio)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<xdlc_devices;i++){
|
||||
if (!sock_fd[i].sock)
|
||||
continue;
|
||||
|
||||
ioctl(sock_fd[i].sock,WAN_DEVPRIV_SIOC(SIOCS_XDLC_STOP),NULL);
|
||||
|
||||
close(sock_fd[i].sock);
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
void new_max_sock_fd(void)
|
||||
{
|
||||
int i;
|
||||
max_sock_fd=0;
|
||||
for (i=0;i<xdlc_devices;i++){
|
||||
if (sock_fd[i].sock > max_sock_fd){
|
||||
max_sock_fd=sock_fd[i].sock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void close_connection(int i)
|
||||
{
|
||||
|
||||
printf("%s: Connection SockId=%i closed: Tx=%i Rx=%i\n",
|
||||
prognamed,
|
||||
sock_fd[i].sock,
|
||||
sock_fd[i].tx,
|
||||
sock_fd[i].rx);
|
||||
|
||||
ioctl(sock_fd[i].sock,WAN_DEVPRIV_SIOC(SIOCS_XDLC_STOP),NULL);
|
||||
close(sock_fd[i].sock);
|
||||
|
||||
if (max_sock_fd == sock_fd[i].sock){
|
||||
sock_fd[i].sock=0;
|
||||
new_max_sock_fd();
|
||||
//printf("%s: Finding new max sock %i\n",prognamed,max_sock_fd);
|
||||
}
|
||||
sock_fd[i].sock=0;
|
||||
}
|
||||
|
||||
int xdlc_get_numof_devices(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<MAX_SOCK_NUM;i++){
|
||||
|
||||
if (primary_enable){
|
||||
if (xdlc_dev_pri_map[i] == NULL)
|
||||
break;
|
||||
}else{
|
||||
if (xdlc_dev_sec_map[i] == NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
install_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
|
||||
|
||||
PROD=wanrouter
|
||||
START_SCRIPT=S20wanrouter
|
||||
STOP_SCRIPT=K10wanrouter
|
||||
PROD_INIT=/usr/sbin/wanrouter
|
||||
|
||||
# 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/rc5.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
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
if [ -d "/usr/local/wanrouter" ]; then
|
||||
cat <<EOM
|
||||
|
||||
*** Previous installation of Wanpipe detected.
|
||||
Please use /usr/sbin/wancfg instead of /usr/local/wanrouter/wancfg
|
||||
for Wanpipe configuration.
|
||||
The new configuration files will be saved in /etc/wanpipe
|
||||
and /etc/wanpipe/interfaces directories.
|
||||
|
||||
EOM
|
||||
else
|
||||
echo 'no old wanpipe detected' > /dev/null
|
||||
fi
|
||||
|
||||
cat <<EOM
|
||||
|
||||
*** Sangoma Wanpipe was successfully installed.
|
||||
Run wancfg command to configure wanpipe.
|
||||
Refer to /usr/share/doc/wanpipe for documentation.
|
||||
|
||||
Docs: README-2.config
|
||||
README-3.operation
|
||||
README-4.debugging
|
||||
|
||||
Hardware Probe: /usr/sbin/wanrouter hwprobe
|
||||
Wanpipe Config: /usr/sbin/wancfg
|
||||
Wanpipe Start : /usr/sbin/wanrouter start
|
||||
|
||||
EOM
|
||||
|
||||
install_init;
|
||||
|
||||
#check dependancies for the new modules
|
||||
eval "depmod -a > /dev/null 2> /dev/null &"
|
||||
echo
|
||||
|
||||
eval "modprobe wanrouter"
|
||||
if [ $? -eq 0 ]; then
|
||||
modprobe -r wanrouter 2>> /dev/null
|
||||
else
|
||||
echo "Failed to load wanpipe modules!"
|
||||
echo
|
||||
echo "Make sure you are installing correct RPMS for your system!"
|
||||
echo
|
||||
echo "Otherwise call Sangoma Tech Support"
|
||||
fi
|
||||
|
||||
exit 0;
|
|
@ -0,0 +1,43 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
echo "Uninstalling WANPIPE..."
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 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
|
||||
|
||||
PROD=wanrouter
|
||||
START_SCRIPT=S20wanrouter
|
||||
STOP_SCRIPT=K10wanrouter
|
||||
PROD_INIT=/usr/sbin/wanrouter
|
||||
|
||||
echo "Removing WANPIPE start-up scripts: $RC_DIR"
|
||||
rm -f $RC_DIR/rc2.d/$START_SCRIPT
|
||||
rm -f $RC_DIR/rc3.d/$START_SCRIPT
|
||||
rm -f $RC_DIR/rc4.d/$START_SCRIPT
|
||||
rm -f $RC_DIR/rc5.d/$START_SCRIPT
|
||||
|
||||
rm -f $RC_DIR/rc0.d/$STOP_SCRIPT
|
||||
rm -f $RC_DIR/rc1.d/$STOP_SCRIPT
|
||||
rm -f $RC_DIR/rc6.d/$STOP_SCRIPT
|
||||
|
||||
rm -f $RC_DIR/init.d/$PROD
|
||||
return 0
|
||||
}
|
||||
|
||||
#remove start-on-boot scripts
|
||||
remove_init;
|
||||
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,17 @@
|
|||
Package: wanpipe
|
||||
Version: 2.3.2-7
|
||||
Section: networking
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
Essential: no
|
||||
Depends: libncurses5-dev,libc6,libc6-dev,perl
|
||||
Pre-Depends:
|
||||
Recommends:
|
||||
Suggests:
|
||||
Installed-Size: 1024
|
||||
Maintainer: Nenad Corbic [ncorbic@sangoma.com]
|
||||
Conflicts:
|
||||
Replaces:
|
||||
Provides: wanpipe
|
||||
Description: WANPIPE S-series is a family of intelligent multi-protocol WAN adapters that support data transfer rates up to 4Mbps. All WAN protocols supported by WANPIPE are implemented in firmware and run on the card. An advantage of an intelligent adapter is that it offloads the system CPU and improves stability. By adding a Sangoma WAN component to the Linux kernel, one can create a powerful multi-T1 router/firewall with proven reliability of Linux. Sangoma S-series cards support an optional on board CSU/DSU that eliminates all external components of a traditional routing solution. The T1 line can be directly connected to the card. WANPIPE supports the following protocols, Frame Relay, X25(API), PPP, MULTILINK PPP and CHDLC. Furthermore, WANPIPE supports custom API development such as: Credit card verification, Voice-over IP, Satellite Comm. All device drivers are part of the standard Linux Kernel distribution.
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
October 19, 1995
|
||||
|
||||
Sangoma Technologies Inc. announces availability
|
||||
of Alpha-version of Frame Relay implementation
|
||||
for Linux operating system
|
||||
|
||||
|
||||
Alpha version of Sangoma Frame Relay for Linux is now available to
|
||||
all interested parties.
|
||||
|
||||
Frame Relay support for Linux is based on Sangoma's intelligent
|
||||
multi-protocol Synchronous Data Link Adapters (SDLA) and implemented
|
||||
as a set of kernel loadable modules allowing users to load drivers
|
||||
as needed and unload them without re-booting their computers.
|
||||
|
||||
Drivers form two-level hierarchy:
|
||||
|
||||
o SDLA driver is responsible for controlling SDLA hardware and
|
||||
provides foundation for upper-level protocol-specific drivers
|
||||
such as Frame Relay, X.25, PPP, HDLC, SDLC, Bisync, etc.
|
||||
|
||||
o Frame Relay driver (called FLIP) integrates SDLA into Linux
|
||||
TCP/IP protocol stack.
|
||||
|
||||
Both levels are fully dynamically configurable.
|
||||
|
||||
Following are the key features of Sangoma Frame Relay implementation
|
||||
for Linux:
|
||||
|
||||
o Support for up to eight SDLA cards. Different SDLA types can
|
||||
be installed in one machine and supported by the same driver.
|
||||
|
||||
o SDLA driver automatically detects adapter type and performs
|
||||
adapter autoconfiguration, where possible.
|
||||
|
||||
o SDLA driver allows to change hardware configuration dynamically,
|
||||
without re-linking the kernel, re-booting PC or re-loading the
|
||||
driver.
|
||||
|
||||
o Frame Relay driver can be dynamically bound to multiple SDLA
|
||||
cards (Frame Relay ports). All Frame Relay ports are
|
||||
independently configurable.
|
||||
|
||||
o Linux network interfaces can be created dynamically and assigned
|
||||
to particular DLCI's on any Frame Relay port.
|
||||
|
||||
Software is distributed under the GNU General Public License and
|
||||
can be downloaded from Sangoma's FTP site on the Internet:
|
||||
|
||||
ftp://www.sangoma.com/pub/sdlaflip.tgz
|
||||
|
||||
Contact Information
|
||||
|
||||
Sangoma Technologies Inc.
|
||||
Phone: (905) 474-1990
|
||||
Fax: (905) 474-9223
|
||||
Hotline: 1-800-388-2475
|
||||
E-mail: dm@sangoma.com
|
||||
|
Binary file not shown.
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,22 @@
|
|||
WANPIPE S-series is a family of intelligent
|
||||
multi-protocol WAN adapters that support data
|
||||
transfer rates up to 4Mbps. All WAN protocols
|
||||
supported by WANPIPE are implemented in firmware
|
||||
and run on the card. An advantage of an
|
||||
intelligent adapter is that it offloads the system
|
||||
CPU and improves stability. By adding a Sangoma
|
||||
WAN component to the Linux kernel, one can create
|
||||
a powerful multi-T1/E1 router/firewall with proven
|
||||
reliability of Linux. Sangoma S-series cards
|
||||
support an optional on board CSU/DSU that
|
||||
eliminates all external components of a
|
||||
traditional routing solution: T1/E1 lines can be
|
||||
directly connected to the card. WANPIPE supports
|
||||
the following WAN protocols: Frame Relay, X25(API),
|
||||
PPP, MULTILINK PPP, CHDLC, SS7(API), BISYNC(API),
|
||||
and SDLC(API). Furthermore, WANPIPE supports ADSL
|
||||
cards with drivers developed and optimized for Linux.
|
||||
WANPIPE contains custom API development packages for:
|
||||
Credit card verification, Voice-over IP and Satellite
|
||||
Comm. All device drivers are part of the standard
|
||||
Linux Kernel distribution.
|
|
@ -0,0 +1,81 @@
|
|||
LIMITED USE LICENSE AGREEMENT
|
||||
|
||||
Sangoma Technologies Inc. provides the computer software program contained on
|
||||
the medium in this package (hereinafter called the Program) and licenses its
|
||||
use.
|
||||
|
||||
THE LICENSEE SHOULD CAREFULLY READ THE FOLLOWING TERMS AND CONDITIONS BEFORE
|
||||
ATTEMPTING TO USE THIS PRODUCT. INSERTION OF ANY OF THE DISKETTES IN THIS
|
||||
PACKAGE INTO ANY MACHINE INDICATES THE LICENSEE'S ACCEPTANCE OF THESE TERMS
|
||||
AND CONDITIONS. IF THE LICENSEE DOES NOT AGREE WITH THE TERMS AND CONDITIONS,
|
||||
THE LICENSEE SHOULD PROMPTLY RETURN THE PACKAGE WITHIN 15 DAYS UNUSED AND
|
||||
UNCOPIED IN ANY WAY SHAPE OR FORM, AND MONIES WILL BE REFUNDED.
|
||||
|
||||
0.2 LICENSE:
|
||||
|
||||
a. The purchaser of this license (hereinafter called the Licensee) is
|
||||
granted a personal, non-exclusive license to use the Program in
|
||||
accordance with the terms and conditions set out in this agreement.
|
||||
|
||||
b. The Program may be used only on a single computer per license granted.
|
||||
|
||||
c. The Licensee and the Licensee's agents and employees shall protect the
|
||||
confidentiality of the Program and shall not distribute or make available
|
||||
the Program or documentation to any third party.
|
||||
|
||||
d. The Licensee may copy the programs into machine readable or printed form
|
||||
for backup or modification purposes only in support of the Licensee's use
|
||||
on a single machine. The Licensee must reproduce and include the
|
||||
copyright notice on any copy, modification or portion merged into another
|
||||
program.
|
||||
|
||||
e. Any portion of the Program merged into or used in conjunction with
|
||||
another program will continue to be subject to the terms and conditions
|
||||
of this agreement.
|
||||
|
||||
f. The Licensee may not assign or transfer the license or the program to any
|
||||
third party without the express prior consent of Sangoma Technologies
|
||||
Inc.
|
||||
|
||||
g. The licensee acknowledges that this license is only a limited license to
|
||||
use the Program and documentation, and that Sangoma Technologies Inc.
|
||||
retains full title to the program and documentation.
|
||||
|
||||
h. The Licensee shall not use, copy, modify or transfer the Program or
|
||||
documentation or any copy, modification or merged portion, in whole or in
|
||||
part, except as expressly provided for in this license. If the Licensee
|
||||
transfers possession of any copy, modification or merged portion of the
|
||||
program to a third party, the license is automatically terminated under
|
||||
this agreement.
|
||||
|
||||
0.3 TERM:
|
||||
|
||||
The license is effective until terminated. The licensee may terminate the
|
||||
license at any time by destroying the Program together with all copies,
|
||||
modifications and merged portion in any form. The Licensee agrees upon such
|
||||
termination to destroy the Program together with all copies, modifications and
|
||||
merged portion in any form.
|
||||
|
||||
0.4 LIMITED WARRANTY:
|
||||
|
||||
The Program is provided "as is" without warranty of any kind, either expressed
|
||||
or implied, including, but not limited to, the implied warranties of
|
||||
merchantability and fitness for a particular purpose. The entire risk as to
|
||||
the performance of the Program is with the Licensee. Should the Program prove
|
||||
defective, the Licensee (and not Sangoma Technologies Inc. or an authorized
|
||||
dealer) shall assume the entire cost of all necessary servicing, or
|
||||
correction. However, Sangoma Technologies Inc. warrants the diskettes on which
|
||||
the Program is furnished will be free of defects in materials or workmanship
|
||||
under normal use for a period of 90 days from the date of delivery to the
|
||||
Licensee. In no event will Sangoma Technologies Inc. be liable for any
|
||||
damages, including incidental or consequential damages arising out of the use
|
||||
or inability to use the Program, even if Sangoma Technologies Inc. or an
|
||||
authorized dealer have been advised of the possibility of such damages, or for
|
||||
any claim by any other party.
|
||||
|
||||
The Licensee acknowledges that the Licensee has read this agreement,
|
||||
understands it, and agrees to be bound by its terms and conditions. The
|
||||
Licensee further agrees that it is the complete and exclusive statement of the
|
||||
agreement between the parties and supersedes any proposal or prior agreement,
|
||||
oral or written, and any other communications between the parties relating to
|
||||
the subject matter of this agreement.
|
|
@ -0,0 +1,492 @@
|
|||
WANPIPE OFFICIAL RELEASE CHANGE LOG
|
||||
===================================
|
||||
|
||||
|
||||
Author: Nenad Corbic <ncorbic@sangoma.com>
|
||||
|
||||
|
||||
Wanpipe Linux Web Page:
|
||||
-------------------
|
||||
Sign-up to receive email notification of driver changes
|
||||
and updates for WANPIPE under Linux.
|
||||
|
||||
http://www.sangoma.com/wanpipe_linux/wanpipe_linux_main.htm
|
||||
|
||||
|
||||
IMPORTANT
|
||||
----------
|
||||
|
||||
o From 2.3.0 release forward ADSL drivers can be compiled
|
||||
against any kernel source thanks to the new OS
|
||||
abstraction layer.
|
||||
|
||||
Furthermore, 2.3.0 release contains major architectual
|
||||
driver changes which will allow us to commonise FreeBSD
|
||||
NetBSD and Linux drivers.
|
||||
|
||||
o From 2.2.6 release forward the new S514-7 Dual T/E1,
|
||||
S514-8 Single TE1 and S518 ADSL cards are supproted.
|
||||
|
||||
o From 2.2.4 release forward the new S514-4 T/E1 and S514-5 56K
|
||||
cards are supported.
|
||||
|
||||
o From 2.2.3 release forward ALL wanpipe modules
|
||||
including API modules, can be recompiled from
|
||||
./Setup installation script!
|
||||
NO KERNEL RECOMPILATION is necessary.
|
||||
|
||||
o From 2.2.3 release forward, wanpipe directory
|
||||
architecture has been changed. New home directory
|
||||
for wanpipe is /etc/wanpipe.
|
||||
|
||||
o All old releases are in ../old_releases/wanpipe directory.
|
||||
|
||||
o Custom RPMs can be build based on current kernel image
|
||||
by using the ./Setup buildrpm command.
|
||||
Read the README.rpmbuild.
|
||||
|
||||
|
||||
Jul 14 2003: Release beta8-2.3.0
|
||||
--------------------------------
|
||||
|
||||
o New API sockets
|
||||
|
||||
The MPAPI sockets have replaced the
|
||||
original WANPIPE API sockets. The
|
||||
API interface is 100% backward compatible.
|
||||
|
||||
|
||||
o Wanrouter External Scripts Support
|
||||
|
||||
The /usr/sbin/wanrouter startup script
|
||||
is now able to start external scripts for
|
||||
each action performed on WANPIPE devices.
|
||||
|
||||
|
||||
Script Location:
|
||||
Configurable in /etc/wanpipe/wanrouter.rc
|
||||
|
||||
eg: WAN_SCRITPS_DIR=/etc/wanpipe/scripts/
|
||||
|
||||
|
||||
Interface Start/Stop Scripts:
|
||||
|
||||
<device name>-<interface name>-<cmd>
|
||||
|
||||
eg: wanpipe1-wan0-start
|
||||
wanpipe1-wan0-stop
|
||||
|
||||
|
||||
Interfaces scripts will get invoked by the following commands:
|
||||
|
||||
wanrouter [start|stop|restart]
|
||||
wanrouter [start|stop|restart] <device>
|
||||
wanrouter [start|stop|restart] <device> <interface>
|
||||
|
||||
or dynamically by wanpipe syncppp driver after
|
||||
successfull IPCP negotiation.
|
||||
|
||||
This option is extremely useful for PPPoA ADSL
|
||||
or PPP customers, that need to update their
|
||||
routers based on new negotiated IP addresses.
|
||||
|
||||
Device Start/Stop Scripts:
|
||||
|
||||
<device name>-<cmd>
|
||||
|
||||
eg: wanpipe1-start
|
||||
wanpipe1-stop
|
||||
|
||||
Device scripts will get invoked by the following commands:
|
||||
wanrouter [start|stop|restart]
|
||||
wanrouter [start|stop|restart] <device>
|
||||
|
||||
Global Start/Stop Scripts:
|
||||
|
||||
<cmd>
|
||||
|
||||
eg: start
|
||||
stop
|
||||
|
||||
Global Wanpipe scripts will get invoked by the following commands:
|
||||
wanrouter [start|stop|restart]
|
||||
|
||||
Wancfg Configurator Update
|
||||
|
||||
The /usr/sbin/wancfg configuration utility has
|
||||
been updated to create/edit all external
|
||||
global,device,interface scripts.
|
||||
|
||||
|
||||
Each script is executed as Bash2 shell script.
|
||||
|
||||
|
||||
o Wancfg Configurator Update
|
||||
|
||||
The /usr/sbin/wancfg configuration utility has
|
||||
been updated to create/edit all external
|
||||
global,device,interface scripts.
|
||||
|
||||
|
||||
May 22 2003: Release beta7-2.3.0
|
||||
--------------------------------
|
||||
|
||||
o ADCCP Lapb API Protocol
|
||||
|
||||
New ADCCP Lapb API protocol for
|
||||
S514 and S508 cards.
|
||||
|
||||
Read the REAME.adccp for more info.
|
||||
|
||||
o ADSL Update
|
||||
|
||||
Bug fixes and feature upates to the
|
||||
ADSL code. Including, line watchdog
|
||||
and cell delienation fix.
|
||||
|
||||
Added a line watchdog feature. New config
|
||||
option ADSL_WATCHDOG in wanpipe1.conf.
|
||||
|
||||
New PPPoA ppp driver. No need to use
|
||||
the pppd daemon any more. The whole PPPoA
|
||||
configuration is now inside /usr/sbin/wancfg.
|
||||
|
||||
New Interface Config Options:
|
||||
|
||||
DYN_INTR_CFG: Option enables dynamic ppp ip addressing
|
||||
PAP: Enables pap authentication
|
||||
CHAP: Enables chap authentication
|
||||
USERID: User id
|
||||
PASSWD: User password
|
||||
|
||||
Refer to README.adsl for further info.
|
||||
|
||||
o MPAPI X25 Updates and fixes
|
||||
|
||||
o Updated WANPIPE for
|
||||
RedHat AS 2.1 distribution.
|
||||
|
||||
|
||||
Apr 22 2003: Release beta6-2.3.0
|
||||
--------------------------------
|
||||
|
||||
o ATM firmware update
|
||||
Beta5 had the ATM wrong firmware version,
|
||||
which doesn't work with some ATM switches.
|
||||
|
||||
o Frame Relay bug fix.
|
||||
If running beta4-2.3.0 update to the latest
|
||||
or enable MULTICASTING in network interface
|
||||
protocol setup.
|
||||
|
||||
o ADSL protocol update
|
||||
ADSL driver was too sensitive to noisy lines which
|
||||
caused it to re-train too often.
|
||||
|
||||
ADSL PPPoA has been re-designed. The PPPD Daemon
|
||||
is not used any more. The Wanpipe PPP kernel stack
|
||||
has PAP/CHAP support now.
|
||||
|
||||
Thus whole PPPoA configuration, including PAP/CHAP
|
||||
is now handled by the /usr/sbin/wancfg configurator.
|
||||
|
||||
o New SNMP MIBS
|
||||
New SNMP MIBS for T1/E1/56 front ends
|
||||
Updated original protocol mibs: FR/PPP/CHDLC/X25 ...
|
||||
|
||||
|
||||
Apr 9 2003: Release beta5-2.3.0
|
||||
-------------------------------
|
||||
|
||||
o New ATM driver for S514(T1/E1) cards
|
||||
|
||||
Flexible PHY-layer, supporting all formats of Idle,
|
||||
Unassigned and Physical Layer cells.
|
||||
|
||||
DS1 direct ATM cell mapping as per ITU G.804
|
||||
Section 2.1.
|
||||
|
||||
Support for AAL Type 5.
|
||||
|
||||
ATM operations and management (OAM) support.
|
||||
|
||||
Extensive statistics at both the PHY and ATM levels.
|
||||
|
||||
Real-time data scope with advanced cell-filtering
|
||||
capabilities.
|
||||
|
||||
Unlimited number of VPI/VCI combinations.
|
||||
|
||||
Encapsulation and protocols supported
|
||||
(IP over ATM, PPP over ATM, and Ethernet over ATM)
|
||||
|
||||
o ADSL driver update
|
||||
|
||||
Major bug fixes in ADSL driver.
|
||||
Better retraining algorithm, improved debugging.
|
||||
Better performance on noisy lines.
|
||||
|
||||
o Multi-Protocol Driver Support
|
||||
|
||||
The Multi Protocol drivers implements HDLC/PPP/CHDLC
|
||||
protocols in kernel that run over sangoma dumb
|
||||
card support (S514/S508).
|
||||
|
||||
All Multi Protocol drivers can run on each Sangoma
|
||||
S514/S508 Primary and Secondary Ports.
|
||||
|
||||
o Multi-Protocol API Support
|
||||
|
||||
The Multi Protocol API support runs on top of the
|
||||
Multi Protocol drivers. The MPAPI supports X25/LAPB
|
||||
and DSP protocols as kernel modules.
|
||||
|
||||
All Multi Protocol APIs can run on each Sangoma
|
||||
S514/S508 Primary and Secondary Ports.
|
||||
|
||||
Sample code /etc/wanpipe/api/mpapi/
|
||||
|
||||
The MPAPI support is not released with standard wanpipe
|
||||
release. It must be downloaded separately. For
|
||||
further info contact Sangoma Technologies.
|
||||
|
||||
o Updated Wanpipe Documentation
|
||||
|
||||
New PDF Files: WanpipeInstallation.pdf
|
||||
WanpipeConfiguration.pdf
|
||||
WanpipeOperation.pdf
|
||||
WanpipeDebugging.pdf
|
||||
x25_programming_manual.pdf
|
||||
|
||||
New README Files:
|
||||
There is a README file for
|
||||
each new protocol.
|
||||
|
||||
eg: README.atm, README.adsl...
|
||||
|
||||
New README.faq
|
||||
|
||||
All README files are in doc/ directory or
|
||||
once WANPIPE is installed in /usr/share/doc/wanpipe
|
||||
directory.
|
||||
|
||||
o Updated Wanpipe utilites
|
||||
|
||||
|
||||
|
||||
Feb 21 2003: Release beta4-2.3.0
|
||||
--------------------------------
|
||||
|
||||
o POS (Point of Sale) S509/S515 card support
|
||||
The POS adapters support proprietary protocols
|
||||
such as: IBM 4680, NCR 2126, NCR 1255
|
||||
|
||||
To enable POS card, on installation run:
|
||||
./Setup install --protocol=POS
|
||||
|
||||
|
||||
o ADSL driver update
|
||||
|
||||
o Wanpipe drivers update
|
||||
Wanpipe Event based line debugging
|
||||
|
||||
For Frame Relea, PPP and CHDLC protocols,
|
||||
extensive debugging is outputted to the
|
||||
logs, in case of a protocol, line or
|
||||
hardware error events.
|
||||
|
||||
o Setup installation script update
|
||||
|
||||
When compiling wanpipe drivers two compilation
|
||||
options are offered:
|
||||
|
||||
Compilaton Options: Default or Custom
|
||||
|
||||
Default compilation:
|
||||
Compile the standard WANPIPE protocols
|
||||
into the kernel device driver: Frame Relay, PPP, CHDLC
|
||||
Multi-Port Frame Relay, Multi-Port PPP, and X25(API). "
|
||||
|
||||
Custom compilation:
|
||||
Offer a menu of all available WAN and
|
||||
API protocols. The user will be able to enable
|
||||
protocols individually or all at once,
|
||||
as desired.
|
||||
|
||||
|
||||
|
||||
Jan 7 2003: Release beta3-2.3.0
|
||||
-------------------------------
|
||||
|
||||
o ADSL Update
|
||||
|
||||
Added ATM OAM protocol support
|
||||
OAM Cell loopback is used to test the
|
||||
functionality of the ATM network before
|
||||
the upper layers are enabled.
|
||||
i.e. ATM Ping
|
||||
|
||||
Added further buffer locking mechanism that
|
||||
will further protect buffers on SMP systems.
|
||||
|
||||
o Wanpipemon Update
|
||||
|
||||
Added ADSL ATM Cell trace option
|
||||
(tl2) to ADSL debugger.
|
||||
|
||||
eg: wanpipemon -i <ifname> -c tl2
|
||||
|
||||
o Frame Relay memory leak bug fix under
|
||||
BRIDGE MODE. If a non ethernet packet was
|
||||
received from the remote network, it was
|
||||
not properly deallocated.
|
||||
|
||||
This condition is very rare but it may occur.
|
||||
|
||||
o Updated ATMARP's for Classical IP over
|
||||
ATM protocol. On startup the Client
|
||||
will send out ATMARPS every 10 seconds.
|
||||
Refer to RFC2225
|
||||
|
||||
o Updated Classical IP over ATM protocol.
|
||||
Maximum MTU=9180 bytes. Specified in RFC2225
|
||||
|
||||
Release beta2 2.3.0
|
||||
--------------------
|
||||
|
||||
o Bug fix in wanrouter.h header
|
||||
The kernel source compilation failed due to
|
||||
a missing header include file in wanrouter.h
|
||||
|
||||
This has been fixed now. No other changes
|
||||
except in wanrouter.h.
|
||||
|
||||
o wanpipemon debugger update
|
||||
|
||||
|
||||
|
||||
|
||||
Dec 04 2002: Release beta1 2.3.0
|
||||
---------------------------------------------
|
||||
|
||||
o ADSL abstraction layer has been added
|
||||
to the main wanpipe source. Thus, from now
|
||||
on ADSL code can be compiled against any
|
||||
custom kernel.
|
||||
|
||||
Added new ATM encapsulation modes:
|
||||
|
||||
Bridged Ethernet LLC over ATM (PPPoE: requires rp-pppoe)
|
||||
Bridged Ethernet VC over ATM
|
||||
Routed IP LLC over ATM (Classical IP)
|
||||
Routed IP VC over ATM
|
||||
PPP LLC over ATM (PPPoA: requires pppd)
|
||||
PPP VC over ATM (PPPoA: requires pppd)
|
||||
|
||||
o Wanpipemon GUI update
|
||||
Better menu system
|
||||
|
||||
o Major driver updates due to new common
|
||||
headers between all protocols and other
|
||||
operating systems (FreeBSD, NetBSD).
|
||||
|
||||
|
||||
Nov 21 2002: Release beta4 2.2.6
|
||||
---------------------------------------------
|
||||
|
||||
o Compilation problems on RedHat 8.0 kernel
|
||||
have been fixed
|
||||
|
||||
|
||||
Oct 30 2002: Release Beta3 2.2.6
|
||||
---------------------------------------------
|
||||
|
||||
o Turns out that RedHat 8 moved the 2.4.20 feature
|
||||
into its 2.4.18 kernel, thus causing the same
|
||||
problem. Thus I had to re-do the fix.
|
||||
|
||||
o Fixed the bug that caused the wanpipe comilation
|
||||
errors when drivers were being compiled into
|
||||
the kernel. (i.e. not modules)
|
||||
|
||||
The current 2.2.6 RPMS are not affected by this bug, since
|
||||
they were compiled for older kernels (not 2.4.20).
|
||||
|
||||
|
||||
Oct 30 2002: Release Beta2 2.2.6
|
||||
--------------------------------
|
||||
|
||||
o Due to the change in 2.4.20 kernel all wanpipe
|
||||
network interfaces failed on startup.
|
||||
|
||||
A fix was a one liner, however it had to be
|
||||
applied to all protocols.
|
||||
|
||||
|
||||
|
||||
Oct 22 2002: Release Beta1 2.2.6
|
||||
--------------------------------
|
||||
|
||||
o Support for new hardware:
|
||||
S5147 - Dual T1/E1 card
|
||||
S5148 - T1/E1 card
|
||||
S518 - ADSL card
|
||||
|
||||
o New ADSL drivers
|
||||
Ethernet of ATM (IPoE and PPPoE)
|
||||
Classical IP of ATM
|
||||
|
||||
o Updated drivers for all protocols
|
||||
|
||||
o A unified debugging tool 'wanpipemon'
|
||||
that replaces protocol specific debugging
|
||||
tools (fpipemon, cpipemon, xpipemon ...)
|
||||
|
||||
GUI support for wanpipemon
|
||||
|
||||
o Update 'wancfg' configuration tool
|
||||
|
||||
o Updated documentation
|
||||
|
||||
o Frame Relay Feature
|
||||
Auto DLCI configuration for a single DLCI.
|
||||
The /usr/sbin/wancfg will offer the auto
|
||||
option if FR is configured for CPE and
|
||||
a Single DLCI.
|
||||
|
||||
o New MultiPort Frame Relay Driver
|
||||
|
||||
This new Frame Relay driver can operate on both
|
||||
S514/S508 PRIMARY and SECONDARY ports.
|
||||
|
||||
Thus, on a single S5141 card one can run CHDLC,
|
||||
and FR on each port.
|
||||
|
||||
On a S5142 card on can run CHDLC, MPPP and MFR
|
||||
protocols on each 4 ports.
|
||||
|
||||
o SDLC support for Linux
|
||||
API for SDLC protocol
|
||||
|
||||
o Update to /usr/sbin/wanrouter
|
||||
|
||||
wanrouter debug
|
||||
Check current wanpipe environment.
|
||||
After a startup error run this command to
|
||||
get a possible solution
|
||||
i.e. wanrouter start; wanrouter debug;
|
||||
|
||||
wanrouter debug if_name
|
||||
Display common debugging statistics
|
||||
In case of line problems save to file,
|
||||
wait 2-5mi and send to Sangoma Tech Support
|
||||
i.e. wanrouter debug wp1fr16 > debug_file;
|
||||
|
||||
wanrouter messages
|
||||
Display wanpipe kernel event messages
|
||||
i.e. /var/log/messages
|
||||
|
||||
wanrouter conflog
|
||||
Display wanpipe configuration parsing messages
|
||||
i.e. /var/log/wanrouter
|
||||
|
|
@ -0,0 +1,396 @@
|
|||
WANPIPE PACKAGE INSTALLATION/UN-INSTALLATION
|
||||
============================================
|
||||
|
||||
Author: Nenad Corbic
|
||||
|
||||
|
||||
WANPIPE PACKAGES
|
||||
================
|
||||
|
||||
Wanpipe RPM packages are located in:
|
||||
ftp.sangoma.com/linux/RPMS
|
||||
|
||||
Please refer to RPM package installation
|
||||
below.
|
||||
|
||||
|
||||
Wanpipe SOURCE packages are located in:
|
||||
ftp.sangoma.com/linux/current_wanpipe
|
||||
|
||||
Download the latest SOURCE wanpipe release
|
||||
in ANY directory:
|
||||
ex: cd /tmp
|
||||
tar xvfz wanpipe-<version>.tgz
|
||||
|
||||
The tar will create the temporary
|
||||
wanpipe/ directory.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE SOURCE PACKAGE Installation
|
||||
====================================
|
||||
|
||||
The 'Setup' script located in temporary wanpipe/
|
||||
directory should be used to install/un-install
|
||||
and re-configure all WANPIPE driver and utilities.
|
||||
|
||||
The Setup installation script contains numerous
|
||||
options that can be used to customise wanpipe
|
||||
installation. Run ./Setup without any arguments
|
||||
for usage.
|
||||
|
||||
Run the Setup script from temporary wanpipe/ directory
|
||||
(wanpipe directory was created by untaring the source package)
|
||||
|
||||
cd wanpipe/
|
||||
|
||||
./Setup install
|
||||
|
||||
The install option will do the following:
|
||||
-------
|
||||
1. Check that all WANPIPE files are accounted for.
|
||||
|
||||
2. Check/modify permissions on all WANPIPE files.
|
||||
|
||||
3. Prompt the user to Install/Upgrade WANPIPE
|
||||
drivers into the Linux kernel source.
|
||||
|
||||
NOTE: The kernel source must be located
|
||||
in /usr/src/linux.
|
||||
|
||||
Or the linux source directory
|
||||
must be supplied with '--with-linux' argument.
|
||||
|
||||
It is always RECOMMENDED to upgrade/update
|
||||
the kernel source tree with the latest
|
||||
wanpipe source.
|
||||
|
||||
4. Prompt the user to re-compile all WANPIPE
|
||||
kernel drivers and install them as modules
|
||||
in the the current /lib/modules/<kernel-version>
|
||||
directory.
|
||||
|
||||
Compilaton Options: Default or Custom
|
||||
|
||||
Default compilation:
|
||||
option will compile the standard WANPIPE protocols
|
||||
into the kernel device driver: Frame Relay, PPP, CHDLC
|
||||
Multi-Port Frame Relay, Multi-Port PPP, and X25(API). "
|
||||
|
||||
Custom compilation:
|
||||
option will offer a menu of all available WAN and
|
||||
API protocols. The user will be able to enable
|
||||
protocols individually or all at once,
|
||||
as desired.
|
||||
|
||||
With this option, NO kernel recomilation is
|
||||
necessary :)
|
||||
|
||||
5. Prompt the user to install bootstrap
|
||||
scripts that will be used to start wanpipe
|
||||
during boot up.
|
||||
|
||||
6. Setup the ENVIRONMENT configuration file that will
|
||||
contain directory locations of WANPIPE configuration
|
||||
interface and lock files.
|
||||
|
||||
7. Compile all WANPIPE utilities
|
||||
|
||||
8. Setup the WANPIPE working environment.
|
||||
i.e. Install all binary files into
|
||||
linux file tree.
|
||||
|
||||
/etc/wanpipe : config, library, sample
|
||||
and firmware files.
|
||||
|
||||
/usr/sbin : user space, binary
|
||||
utilites
|
||||
|
||||
/lib/modules/<uname-r> : wanpipe kernel
|
||||
modules
|
||||
|
||||
/usr/share/doc/wanpipe : doc files
|
||||
|
||||
|
||||
The last message in the 'Setup install' sequence will
|
||||
inform you of the next step that you should take
|
||||
in getting WANPIPE working.
|
||||
|
||||
|
||||
o Read 'README-2.config' on how to configure wanpipe
|
||||
device
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CUSTOMIZING WANPIPE SOURCE INSTALLATION
|
||||
=========================================
|
||||
|
||||
Installation using the '--silent' option
|
||||
--------------------------------------
|
||||
|
||||
The '--silent' option is available to install wanpipe
|
||||
without any user interaction:
|
||||
|
||||
./Setup install --silent
|
||||
|
||||
All defaults will be used!
|
||||
--------------------------
|
||||
1. Configuration directory /etc/wanpipe
|
||||
2. Start wanpipe on boot up
|
||||
3. Recompile modules for the kenrel source
|
||||
in /usr/src/linux
|
||||
|
||||
|
||||
|
||||
Installation using the --builddir option
|
||||
--------------------------------------
|
||||
|
||||
When customising the wanpipe package, it is
|
||||
useful to install the package into a
|
||||
virtual directory so not to pollute the
|
||||
current environment.
|
||||
|
||||
This way a user can tar up the temporary
|
||||
directory and create a custom binary
|
||||
WANPIPE package.
|
||||
|
||||
eg ./Setup install --builddir=/tmp/wanpipe_build
|
||||
|
||||
Note: the /tmp/wanpipe_build directory must
|
||||
exist.
|
||||
|
||||
|
||||
|
||||
Installation using the --protocol option
|
||||
--------------------------------------
|
||||
|
||||
Standard Wanpipe installatin will only
|
||||
include MAINSTREAM WAN protocols when building
|
||||
the kernel modules to cut down on kernel
|
||||
module size.
|
||||
|
||||
Mainstream Protocols:
|
||||
Frame Relay, PPP, CHDLC, X25, API stack
|
||||
|
||||
|
||||
To enable NON Mainstream protocols specify
|
||||
extra protocols with the --protocol option.
|
||||
|
||||
Non Mainstream Protocols:
|
||||
BSC : API for Multipoint Bisync
|
||||
BSCSTRM : API for Bisync Streaming
|
||||
SS7 : API for Level2 SS7 protocol
|
||||
EDU : API for Educational software
|
||||
SDLC : API for SDLC protocol
|
||||
POS : API for POS (S515/S509) card.
|
||||
BITSTRM : API for Bitstreaming protocol
|
||||
|
||||
eg: ./Setup install --protocol=<List of Protocols>
|
||||
|
||||
<List of Protocols> = <PROT>-<PROT>-<PROT>
|
||||
|
||||
eg:
|
||||
Compile in Bitstreaming protocol
|
||||
./Setup install --protocol=BITSTRM
|
||||
|
||||
Compile in BitStreaming and POS and SDLC
|
||||
./Setup install --protocol=BITSTRM-POS-SDLC
|
||||
|
||||
|
||||
|
||||
Building a custom RPM
|
||||
---------------------
|
||||
|
||||
./Setup buildrpm <extra options>
|
||||
|
||||
All defaults will be used!
|
||||
--------------------------
|
||||
1. Configuration directory /etc/wanpipe
|
||||
2. Start wanpipe on boot up
|
||||
3. Recompile modules for the kernel source
|
||||
locatd in /usr/src/linux direcotory,
|
||||
or directory supplied with --with-linux=<abs path>
|
||||
argument.
|
||||
|
||||
|
||||
|
||||
Note: <extra options> start with -- and are defined above.
|
||||
|
||||
i.e.
|
||||
user the --protocol filed to add in extra protocols
|
||||
into the wanpipe kernel modules.
|
||||
|
||||
Refer to README.rpmbuild
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE Kernel Driver Compile/Update
|
||||
====================================
|
||||
|
||||
This option should be used to update the kernel
|
||||
source tree with the latest wanpipe drivers
|
||||
and to compile the wanpipe kernel modules
|
||||
against the updated kernel source tree.
|
||||
|
||||
Run the Setup script in temporary wanpipe/ directory:
|
||||
|
||||
ex: cd wanpipe/
|
||||
|
||||
./Setup drivers
|
||||
|
||||
The drivers option will do the following:
|
||||
-------
|
||||
1. Prompt the user to Install/Upgrade Wanpipe
|
||||
drivers into the Linux kernel source.
|
||||
|
||||
NOTE: The kernel source must be located
|
||||
in /usr/src/linux
|
||||
|
||||
It is always RECOMMENDED to upgrade/update
|
||||
the kernel source tree with the latest
|
||||
wanpipe source.
|
||||
|
||||
2. Prompt the user to re-compile all WANPIPE
|
||||
kernel drivers and install the as modules
|
||||
in the the current /lib/modules/<kernel-version>
|
||||
directory.
|
||||
|
||||
Compilaton Options: Default or Custom
|
||||
|
||||
Default compilation:
|
||||
option will compile the standard WANPIPE protocols
|
||||
into the kernel device driver: Frame Relay, PPP, CHDLC
|
||||
Multi-Port Frame Relay, Multi-Port PPP, and X25(API). "
|
||||
|
||||
Custom compilation:
|
||||
option will offer a menu of all available WAN and
|
||||
API protocols. The user will be able to enable
|
||||
protocols individually or all at once,
|
||||
as desired.
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE Utilities Re-Compilation
|
||||
=================================
|
||||
|
||||
This option will re-compile all WANPIPE utilities
|
||||
in temporary wanpipe/ directory.
|
||||
|
||||
NOTE: If this is a first time install you MUST run
|
||||
the install option: Setup install.
|
||||
|
||||
Run the Setup script in temporary wanpipe/ directory:
|
||||
|
||||
ex: cd wanpipe/
|
||||
./Setup utility
|
||||
|
||||
The utility option will do the following:
|
||||
-------
|
||||
1. Compile all WANPIPE utilities
|
||||
in temporary wanpipe/ directory
|
||||
|
||||
To install utilities into /usr/sbin
|
||||
directory one must run:
|
||||
|
||||
./Setup inst
|
||||
|
||||
|
||||
For more info about Setup command run
|
||||
./Setup without any arguments for full usage
|
||||
info.
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE Un-Install
|
||||
==================
|
||||
|
||||
Run the Setup script in temporary wanpipe/ directory:
|
||||
|
||||
ex: cd wanpipe/
|
||||
./Setup remove
|
||||
|
||||
|
||||
The remove option will do the following:
|
||||
------
|
||||
1. Remove all boot strap WANPIPE scripts.
|
||||
2. Remove all utilities from /usr/sbin,
|
||||
/etc/wanpipe, /usr/share/doc/wanpipe
|
||||
directories.
|
||||
|
||||
After the 'Setup remove' command, it is safe
|
||||
to remove the whole temporary wanpipe/ directory.
|
||||
|
||||
ex:
|
||||
rm -rf wanpipe/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE RPM PACKAGE Installation
|
||||
================================
|
||||
|
||||
Choosing an RPM:
|
||||
--------------
|
||||
|
||||
o Determine the Linux Distribution:
|
||||
cat /etc/issue
|
||||
(eg: RedHat 7.1)
|
||||
|
||||
o Determine the Kernel image you are running:
|
||||
uname -r
|
||||
(eg: 2.4.2-2 : it is not an smp kernel)
|
||||
(eg: 2.4.2-2smp : smp kernel)
|
||||
|
||||
o Determine the processor type
|
||||
uname -m
|
||||
(eg: i686)
|
||||
|
||||
o Based on the above information choose an RPM package.
|
||||
|
||||
wanpipe-<version>.<linux distrib>.<kernel ver>.<processor>.rpm
|
||||
|
||||
eg: ftp.sangoma.com/linux/RPM/redhat/7.1/i686/
|
||||
wanpipe-2.2.4-3.rh71up.k242-2.i686.rpm
|
||||
|
||||
|
||||
|
||||
Installing RPM
|
||||
----------
|
||||
|
||||
o List the contents of the rpm
|
||||
|
||||
rpm -qipl <wanpipe rpm name>
|
||||
|
||||
Make sure that the /lib/modules/<kernel name> directory
|
||||
matches your current kernel modules directory.
|
||||
|
||||
i.e. the output of command 'uname -r' must match the above
|
||||
<kernel name> directory.
|
||||
|
||||
|
||||
o The rpm must be installed using the --force option, to
|
||||
override the old modules.
|
||||
|
||||
rpm -i --force <wanpipe rpm name>
|
||||
|
||||
|
||||
o Read 'README-2.config' on how to configure wanpipe
|
||||
device
|
||||
|
||||
|
||||
|
||||
For further info, refer to WanpipeInstallation.pdf
|
|
@ -0,0 +1,376 @@
|
|||
Wanpipe Configuration
|
||||
======================
|
||||
|
||||
Before starting WANPIPE, a configuration file (wanpipeN.conf, where
|
||||
N=1,2,3..etc.)must be created in /etc/wanpipe directory.
|
||||
This file contains the line, hardware and interface definitions
|
||||
for the WAN connection.
|
||||
|
||||
RELEASE 2.3.2 and on:
|
||||
The new WANCFG utility has been release. It should
|
||||
be used to configure standard WAN protocols like:
|
||||
FR, PPP, CHDLC,
|
||||
MULTILINK PPP (TTY), TDM_VOICE
|
||||
HDLC API
|
||||
ADSL
|
||||
|
||||
|
||||
For both AFT and S514 series cards.
|
||||
|
||||
The old WANCFG utility has been renamed to wancfg_legacy.
|
||||
This utility should be used for all API protocols like:
|
||||
X25, SDLC, BITSTREAMING ...
|
||||
|
||||
|
||||
The program /usr/sbin/wancfg should be used to create the
|
||||
configuration file(s). It is a GUI, ncurses based,
|
||||
configurator that contains all wanpipe options
|
||||
as well as extended help information on each
|
||||
option.
|
||||
|
||||
In case wancfg is not used, i.e. embedded systems, use
|
||||
the sample configuration files located in
|
||||
/etc/wanpipe/samples directory.
|
||||
|
||||
|
||||
Things you should know before starting /usr/sbin/wancfg:
|
||||
|
||||
1. Protocol:
|
||||
Frame Relay, MulitPort Frame Relay,
|
||||
CHDLC, PPP, MultiPort PPP, ADSL, X25 ...
|
||||
|
||||
2. Protocol/IP Info:
|
||||
Frame Relay: Type of Status Signaling (LMI,
|
||||
ANSI, or Q.933
|
||||
Number of DLCI to configure
|
||||
DLCI numbers
|
||||
IP info for each DLCI
|
||||
|
||||
CHDLC: IP info
|
||||
|
||||
PPP: IP info
|
||||
|
||||
X25: Maximum packet size
|
||||
Number of SVCs/PVCs
|
||||
IP info
|
||||
|
||||
ADSL: ATM encapsulation:
|
||||
Bridged Ethernet LLC over ATM: (PPPoE)
|
||||
Bridged Ethernet VC over ATM
|
||||
Classical IP LLC over ATM
|
||||
Router IP VC over ATM
|
||||
PPP LLC over ATM
|
||||
PPP VC over ATM: (PPPoA)
|
||||
|
||||
ATM configuration:
|
||||
VPI and VCI
|
||||
|
||||
If not available use the auto
|
||||
config option to autodetect
|
||||
these values.
|
||||
|
||||
IP Info: (Not needed for PPPoE)
|
||||
|
||||
NOTE:
|
||||
For PPPoE and PPPoA setup please refer to
|
||||
APPENDIX A below.
|
||||
|
||||
ATM: ATM encapsulation:
|
||||
Bridged Ethernet LLC over ATM: (PPPoE)
|
||||
Bridged Ethernet VC over ATM
|
||||
Classical IP LLC over ATM
|
||||
Router IP VC over ATM
|
||||
|
||||
ATM configuration:
|
||||
VPI and VCI
|
||||
|
||||
IP Info: (Not needed for PPPoE)
|
||||
|
||||
3. CSU/DSU Info:
|
||||
|
||||
T1/E1: Encoding
|
||||
Framing
|
||||
Active Channels/Baud Rate
|
||||
|
||||
56K: Internal or External Clocking
|
||||
Internal clocking should only be used
|
||||
in back to back situations.
|
||||
Default: External
|
||||
|
||||
|
||||
For the rest of this document, we will assume we are working with the
|
||||
following ISP/Telco supplied data:
|
||||
|
||||
|
||||
Protocol: Frame Relay
|
||||
Prot Info:
|
||||
Num of DLCI's = 2
|
||||
DLCI=16 and 17
|
||||
|
||||
IP Info: DLCI 16
|
||||
Local =201.1.1.1
|
||||
PtoP =201.1.1.2
|
||||
Netmask =255.255.255.0
|
||||
Gateway =201.1.1.2 (i.e. this is the system
|
||||
default gateway)
|
||||
|
||||
DLCI 17
|
||||
Local =202.1.1.1
|
||||
PtoP =202.1.1.2
|
||||
Netmask =255.255.255.0
|
||||
Gateway =N/A
|
||||
|
||||
|
||||
|
||||
WANCFG
|
||||
======
|
||||
|
||||
IMPORTANT:
|
||||
Use the "ADVANCED" sections only for non
|
||||
standard configurations, otherwise leave
|
||||
them default.
|
||||
|
||||
|
||||
1. Start /usr/sbin/wancfg
|
||||
|
||||
2. Select Create opton
|
||||
|
||||
3. Select Card from Hardware Probe
|
||||
|
||||
4. Specify Hardware information:
|
||||
T1/E1/V35
|
||||
|
||||
5. Specify Protocol
|
||||
FR,PPP,CHDLC,TTY(Multilink PPP) ...
|
||||
|
||||
Frame Relay is by default configured
|
||||
for Auto DLCI. Use the advanced sections
|
||||
to change this.
|
||||
|
||||
6. Network Interface Setup
|
||||
|
||||
Specify Operation mode:
|
||||
|
||||
WANPIPE: IP mode proceed to specify IP addresss
|
||||
API: Custom API mode, no IP addresses
|
||||
|
||||
Specify IP addresses:
|
||||
|
||||
7. Save and exit
|
||||
|
||||
|
||||
For old WANCFG_LEGACY example refer to APPENDIX B below!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Troubleshooting the driver load process
|
||||
=======================================
|
||||
|
||||
After a startup failure run wanrouter debug
|
||||
option for more information and possible solutions:
|
||||
|
||||
wanrouter debug
|
||||
|
||||
|
||||
Syntax Errors:
|
||||
--------------
|
||||
|
||||
All wanpipe configuration file syntax errors are
|
||||
reported in /var/log/wanrouter
|
||||
|
||||
wanrouter conflogs
|
||||
|
||||
|
||||
Driver Messages:
|
||||
----------------
|
||||
|
||||
All wanpipe driver events will be recorded in
|
||||
/var/log/messages.
|
||||
|
||||
Thus if errors occur, first check /var/log/messages
|
||||
to find out what exactly went wrong
|
||||
with the drivers startup.
|
||||
|
||||
wanrouter messages
|
||||
|
||||
or
|
||||
|
||||
tail -f /var/log/messages
|
||||
|
||||
Once the device is started you should see a
|
||||
"link connecting" message. This message
|
||||
indicates that the card was been configured
|
||||
successfully and that the link is trying to
|
||||
connect.
|
||||
|
||||
|
||||
Wanpipe Debugger:
|
||||
-----------------
|
||||
|
||||
/usr/sbin/wanpipemon should be used to further debug
|
||||
hardware, line and protocol problems.
|
||||
|
||||
/usr/sbin/wanpipemon -g
|
||||
|
||||
|
||||
|
||||
Sangoma Tech Support:
|
||||
---------------------
|
||||
|
||||
When reporting problems to Sangoma Tech Support please
|
||||
dump the current system debug information into
|
||||
a temporary file and send it via email.
|
||||
|
||||
1. wanrouter debug if_name > sangoma_debug_file.txt
|
||||
(where if_name is wanpipe interface name: eg wp1fr16)
|
||||
|
||||
2. Wait for 2-5 minutes
|
||||
|
||||
3. Stop the debug by pressing ENTER
|
||||
|
||||
4. Email sangoma_debug_file.txt to Sangoma Tech Support
|
||||
|
||||
|
||||
Refer to README-4.debugging
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
APPENDIX A: ADSL PPPoE and PPPoA Configuration
|
||||
==========
|
||||
|
||||
Refer to README.adsl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
APPENDIX B: WANCFG_LEGACY (Old Configurator)
|
||||
==========
|
||||
|
||||
1. Start /usr/sbin/wancfg
|
||||
|
||||
2. Select 'Create' option
|
||||
|
||||
3. Select a wanpipe device.
|
||||
If this is a first device select wanpipe1
|
||||
and hit <SELECT> button.
|
||||
|
||||
4. Choose a protocol
|
||||
In this case choose Frame Relay and hit <BACK>
|
||||
button.
|
||||
|
||||
5. Select Hardware Setup
|
||||
|
||||
Probing Hardware:
|
||||
The top option is "Probe Hardware"
|
||||
Select this option and press <ENTER>
|
||||
|
||||
Select a device. When selecting devices
|
||||
note the PORT option. Usually PORT=PRI
|
||||
would be used.
|
||||
|
||||
IMPORTANT:
|
||||
~~~~~~~~~~
|
||||
After the hardware probe section you will
|
||||
notice that the next four fields have
|
||||
been filled out. Thus, adapter type and
|
||||
PCI info should be skipped.
|
||||
|
||||
|
||||
All other options should normally be left as
|
||||
DEFAULT unless you have special information.
|
||||
|
||||
Exit Hardware Setup
|
||||
|
||||
|
||||
6. Network Interface Setup
|
||||
|
||||
|
||||
The network interface set-up depends on the type of connection.
|
||||
|
||||
Instance Frame Relay supports many interfaces, each boud to
|
||||
a DLCI. Thus, there are questions related to the number of
|
||||
DLCIs and configuration information for each DLCI.
|
||||
|
||||
In the case of Point-to-Point protocols like PPP and CHDLC, there
|
||||
is only one interface per physical port.
|
||||
|
||||
This example is Frame Relay with two DLCIs. The first input is:
|
||||
"Please specify the number of DLCIs supported on this Frame Relay
|
||||
connection"
|
||||
|
||||
Enter in number 2
|
||||
|
||||
|
||||
For each network interface do the following:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
DLCI Number:
|
||||
Enter in the DLCI number. Note the default number
|
||||
is always 16.
|
||||
|
||||
Interface Name:
|
||||
The Interface name will also have default value.
|
||||
You can leave it as is or change it. For instance,
|
||||
you could change it to ?chicago? or ?toronto?.
|
||||
|
||||
IMPORTANT:
|
||||
~~~~~~~~~
|
||||
If you are using iptables you might want to change
|
||||
the default interface name to something like "wan0".
|
||||
Iptables and Ipchains don't like "_" in interface
|
||||
name.
|
||||
|
||||
e.g.: 'iptables -o wp1_fr16 ...' will give you an error
|
||||
|
||||
Operation Mode:
|
||||
WANPIPE is for IP Routing
|
||||
BRIDGE is used to attach the network interface to
|
||||
the kernel bridge
|
||||
BRIDGE_NODE is used as a remote end of the line that is
|
||||
connected to a bridge.
|
||||
API is used for custom API applications.
|
||||
Custom socket access to driver.
|
||||
|
||||
DLCI Protocol Setup:
|
||||
In this section leave everything as default.
|
||||
Unless the ISP has specified specific protocol
|
||||
options such as CIR.
|
||||
|
||||
IP Setup:
|
||||
Put in your IP info as supplied by ISP
|
||||
Enable Default gateway for the first
|
||||
interface.
|
||||
|
||||
Note: PointoPoint IP refers to the IP address of
|
||||
the remote router that is connected at
|
||||
the other end of the sync line.
|
||||
|
||||
|
||||
7. Once all network interfaces are setup
|
||||
keep hitting the <BACK> button until
|
||||
Main Menu is reached.
|
||||
|
||||
Then select <EXIT> and save the config
|
||||
file.
|
||||
|
||||
The new config file will be located in
|
||||
/etc/wanpipe directory.
|
||||
|
||||
|
||||
8. Start the device:
|
||||
wanrouter start wanpipe1
|
||||
|
||||
Note: The card doesn't have to be connected to start the wanrouter.
|
||||
|
||||
|
|
@ -0,0 +1,328 @@
|
|||
Wanpipe Operation Manual
|
||||
========================
|
||||
|
||||
|
||||
At the heart of WANPIPE operation is the 'wanrouter' operation
|
||||
script. It is used to start/stop/restart and display
|
||||
WANPIPE current status and environment.
|
||||
|
||||
|
||||
'wanrouter' usage
|
||||
=================
|
||||
|
||||
/usr/sbin/wanrouter <cr>
|
||||
|
||||
|
||||
WANPIPE: WAN Router startup script
|
||||
|
||||
Usage: wanrouter: {options} <wanpipe#> <interface>
|
||||
|
||||
wanrouter start : Starts all devices specified in
|
||||
/etc/wanpipe/wanrouter.rc WAN_DEVICES
|
||||
|
||||
wanrouter stop : Stops all devices specified in
|
||||
/etc/wanpipe/wanrouter.rc WAN_DEVICES
|
||||
|
||||
wanrouter start wanpipe# : Start a single device
|
||||
|
||||
wanrouter stop wanpipe# : Stops a single device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
wanrouter restart : Restart all devices specified in
|
||||
/etc/wanpipe/wanrouter.rc WAN_DEVICES
|
||||
|
||||
wanrouter restart wanpipe# : Restart a single device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
|
||||
wanrouter start wanpipe# if_name : Start a single interface on device
|
||||
|
||||
wanrouter stop wanpipe# if_name : Stops a single interface on device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
wanrouter restart wanpipe# if_name : Restart a single interface on device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
|
||||
wanrouter list : List all active devices
|
||||
|
||||
wanrouter modules : Show wanpipe kernel modules
|
||||
|
||||
wanrouter status : Display status for all active devices
|
||||
|
||||
wanrouter summary : Summary of config files in /etc/wanpipe
|
||||
|
||||
wanrouter hwprobe : Display wanpipe hardware probe info.
|
||||
|
||||
wanrouter debug : Check current wanpipe environment.
|
||||
Wanpipe startup debugging. After a startup error
|
||||
run this command to get a possible solution
|
||||
i.e. wanrouter start; wanrouter debug;
|
||||
|
||||
wanrouter debug if_name : Display common debugging statistics
|
||||
In case of line problems save to file, wait 2-5min
|
||||
and send to Sangoma Tech Support
|
||||
i.e. wanrouter debug wp1fr16 > debug_file;
|
||||
|
||||
wanrouter conflogs : Display wanpipe configuration syntax errors
|
||||
i.e. /var/log/wanrouter
|
||||
|
||||
|
||||
wanrouter messages : Display wanpipe kernel event messages
|
||||
i.e. /var/log/messages
|
||||
|
||||
|
||||
wanrouter version : wanpipe version information.
|
||||
|
||||
|
||||
|
||||
WANPIPE Environment Check
|
||||
=========================
|
||||
|
||||
The wanrouter debug option will check current
|
||||
wanpipe environment, make sure that kernel modules
|
||||
do load, and that /var/log/messages and /var/log/wanrouter
|
||||
logs do not show any errors. It will also try
|
||||
to give possible solutions.
|
||||
|
||||
/usr/sbin/wanrouter debug
|
||||
|
||||
|
||||
Make sure that the new WANPIPE kernel modules have
|
||||
been installed correcty and that they can be loaded
|
||||
into the kernel, and the hardware is detected.
|
||||
|
||||
/usr/sbin/wanrouter hwprobe
|
||||
|
||||
|
||||
Check that a configuration file exists in /etc/wanpipe
|
||||
directory.
|
||||
|
||||
/usr/sbin/wanrouter summary
|
||||
|
||||
|
||||
Make sure that no WANPIPE devices are currently running
|
||||
on the system
|
||||
|
||||
/usr/sbin/wanrouter list
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE Startup
|
||||
===============
|
||||
|
||||
Please note that all kernel driver output messages are
|
||||
located in /var/log/messages file.
|
||||
|
||||
Run 'tail -f /var/log/messages' in a separate console
|
||||
window, to monitor WANPIPE start/stop and operation
|
||||
messages.
|
||||
|
||||
|
||||
To start/stop/restart WANPIPE devices listed in
|
||||
/etc/wanpipe/wanrouter.rc file: (default is wanpipe1)
|
||||
|
||||
/usr/sbin/wanrouter start
|
||||
/usr/sbin/wanrouter stop
|
||||
/usr/sbin/wanrouter restart
|
||||
|
||||
|
||||
To start/stop/restart single wanpipe device: (eg: wanpipe2)
|
||||
|
||||
This command is useful when running multiple devices
|
||||
and would like to operate on a singe device.
|
||||
|
||||
/usr/sbin/wanrouter start wanpipe2
|
||||
/usr/sbin/wanrouter stop wanpipe2
|
||||
/usr/sbin/wanrouter restart wanpipe2
|
||||
|
||||
|
||||
To start/stop/restart a single network interface from a
|
||||
/etc/wanpipe/wanpipe1.conf configuration file:
|
||||
|
||||
This command is useful when adding an extra frame
|
||||
relay DLCI. Also to reconfigure a single DLCI.
|
||||
|
||||
/usr/sbin/wanrouter start wanpipe2 wp2_fr18
|
||||
/usr/sbin/wanrouter stop wanpipe2 wp2_fr18
|
||||
/usr/sbin/wanrouter restart wanpipe2 wp2_fr18
|
||||
|
||||
|
||||
To view current status and configuration of active
|
||||
devices:
|
||||
|
||||
/usr/sbin/wanrouter status
|
||||
|
||||
|
||||
|
||||
Error Debugging
|
||||
===============
|
||||
|
||||
After a failed wanrouter start command
|
||||
run:
|
||||
wanrouter debug
|
||||
|
||||
The debug option will identify an error and
|
||||
offer solutions.
|
||||
|
||||
|
||||
Configuration Syntax Errors:
|
||||
|
||||
All configuration file syntax errors, generated
|
||||
during WANPIPE starup, will be displayed in:
|
||||
|
||||
/var/log/wanrouter
|
||||
|
||||
(eg: cat /var/log/wanrouter)
|
||||
|
||||
|
||||
|
||||
Kernel Driver Errors:
|
||||
|
||||
All device driver errors and events will be
|
||||
displayed in:
|
||||
|
||||
/var/log/messages
|
||||
|
||||
(eg: tail -f /var/log/messages)
|
||||
|
||||
|
||||
Line Errors and Driver Statistics
|
||||
|
||||
After a successful WANPIPE startup any extra
|
||||
debugging, such as line tracing or CSU/DSU
|
||||
debugging will be done using:
|
||||
|
||||
/usr/sbin/wanpipemon -g
|
||||
|
||||
|
||||
For automated Line Error debugging run
|
||||
|
||||
/usr/sbin/wanrouter debug <if_name>
|
||||
|
||||
where <if_name> is wanpipe interface name.
|
||||
|
||||
|
||||
Sangoma Tech Support:
|
||||
---------------------
|
||||
|
||||
When reporting problems to Sangoma Tech Support please
|
||||
dump the current system debug information into
|
||||
a temporary file and send it via email.
|
||||
|
||||
1. wanrouter debug if_name > sangoma_debug_file.txt
|
||||
(where if_name is wanpipe interface name: eg wp1fr16)
|
||||
|
||||
2. Wait for 2-5 minutes
|
||||
|
||||
3. Stop the debug by pressing ENTER
|
||||
|
||||
4. Email sangoma_debug_file.txt to Sangoma Tech Support
|
||||
|
||||
|
||||
Pleae refer to README-4.debugging
|
||||
|
||||
|
||||
|
||||
Wanpipe Power User Operation
|
||||
-----------------------------
|
||||
|
||||
Wanpipe package contents
|
||||
========================
|
||||
|
||||
|
||||
1. Wanpipe Kernel Drivers
|
||||
|
||||
The drivers are listed in order of
|
||||
dependency.
|
||||
|
||||
sdladrv.o : Hardware Layer
|
||||
wanrouter.o : Wanpipe Protocol Interface Layer
|
||||
wanpipe_syncpp.o: Wanpipe PPP/CHDLC Protocol
|
||||
wanpipe.o : Wanpipe multi-protocol layer
|
||||
(Frame-Relay,PPP,CHDLC,...)
|
||||
af_wanpipe.o : Wanpipe API socket layer
|
||||
|
||||
|
||||
|
||||
2. User space programs
|
||||
|
||||
Configuration (/usr/sbin)
|
||||
|
||||
wancfg : Wanpipe configuration tool
|
||||
|
||||
cfgft1 : Wanpipe FT1 config tool for
|
||||
S508FT1 and S5143 cards
|
||||
(For all other cards use wancfg)
|
||||
|
||||
Operation (/usr/sbin)
|
||||
|
||||
wanconfig : Wanpipe operation tool that
|
||||
parses the config file and
|
||||
executed config ioctl() calls to
|
||||
the kernel driver.
|
||||
(C program)
|
||||
|
||||
wanconfig -a /etc/wanpipe/wan_adsl.list card wanpipe1 up
|
||||
|
||||
|
||||
wanrouter : Wanpipe operation script
|
||||
used to start/stop/restart
|
||||
Wanpipe drivers. The wanrouter
|
||||
script uses the above wanconfig
|
||||
to start wanpipe as well as
|
||||
standard "ifconfig" to bring
|
||||
all necessary interfaces up.
|
||||
|
||||
Debugging
|
||||
|
||||
wanpipemon : Wanpipe debugging application
|
||||
used to debug the hardware, drivers
|
||||
and sync line.
|
||||
|
||||
wanpipemon -g
|
||||
|
||||
|
||||
Wanpipe Operation
|
||||
=================
|
||||
|
||||
If a power user desn't want to use
|
||||
the wanrouter master script. Here is the
|
||||
break down of the wanpipe startup
|
||||
sequence:
|
||||
|
||||
wanrouter start
|
||||
|
||||
|
||||
1. Load Kernel Modules
|
||||
|
||||
insmod sdladrv.o
|
||||
insmod wanrouter.o
|
||||
insmod wanpipe_syncppp.o
|
||||
insmod wanpipe.o
|
||||
insmod af_wanpipe.o
|
||||
or
|
||||
|
||||
modprobe af_wanpipe
|
||||
|
||||
2. Configure and Start Drivers
|
||||
|
||||
/usr/sbin/wanconfig -a /etc/wanpipe/wan_adsl.list card wanpipe1 up
|
||||
|
||||
3. Start up all network interfaces
|
||||
|
||||
ifconfig wan0 <local ip> pointopoint <remote ip> netmask 255.255.255.255
|
||||
|
||||
4. Confirmation
|
||||
|
||||
tail -f /var/log/messages
|
||||
|
||||
Check the events and driver statistics.
|
||||
|
||||
cat /proc/net/wanrouter/status
|
||||
|
||||
Check driver state
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
Wanpipe Debugging Manual
|
||||
========================
|
||||
|
||||
Automated Debugging:
|
||||
--------------------
|
||||
|
||||
The wanrouter operation script can retrieve the
|
||||
most common line error statistics that can
|
||||
give the user a good idea of what is going on
|
||||
with the line.
|
||||
|
||||
/usr/sbin/wanrouter debug if_name
|
||||
or
|
||||
/usr/sbin/wanrouter debug if_name > debug_file.txt
|
||||
|
||||
(where if_name is the name of wanpipe interface: eg: wp1fr16)
|
||||
|
||||
|
||||
Sangoma Tech Support:
|
||||
---------------------
|
||||
|
||||
When reporting problems to Sangoma Tech Support please
|
||||
dump the current system debug information into
|
||||
a temporary file and send it via email.
|
||||
|
||||
1. wanrouter debug wp1fr16 > sangoma_debug_file.txt
|
||||
|
||||
2. Wait for 2-5 minutes
|
||||
|
||||
3. Stop the debug by pressing ENTER
|
||||
|
||||
4. Email sangoma_debug_file.txt to Sangoma Tech Support
|
||||
|
||||
|
||||
|
||||
Wanpipe Debugger
|
||||
----------------
|
||||
|
||||
At the heart of WANPIPE debugging is the 'wanpipemon'
|
||||
debugging program. It is used to display line
|
||||
traces, protocol statistics, hardware statistics
|
||||
and configuration parameters.
|
||||
|
||||
|
||||
/usr/sbin/wanpipemon -g
|
||||
|
||||
|
||||
'wanpipemon' usage
|
||||
==================
|
||||
|
||||
/usr/sbin/wanpipemon
|
||||
|
||||
Wanpipemon Verison 1.0
|
||||
Copyright (C) 2002 - Sangoma Technologies
|
||||
www.sangoma.com
|
||||
This may be freely redistributed under the terms of the GNU GPL
|
||||
|
||||
Usage: (Options in {} brackets are optional)
|
||||
|
||||
#Command prompt Local debugging
|
||||
wanpipemon -i <interface> -c <command> { -p <protocol> }
|
||||
|
||||
#Command prompt Remote debugging
|
||||
wanpipemon -i <remote IP> -u <port> -c <command> { -p <protocol> }
|
||||
|
||||
#GUI interface
|
||||
wanpipemon -g { -i <interface|IP> -u <port> -p <protocol> }
|
||||
|
||||
#Display usage for each protocol
|
||||
wanpipemon -p [fr|ppp|chdlc|x25|adsl]
|
||||
|
||||
#Detailed usage for each option
|
||||
wanpipemon -h
|
||||
|
||||
|
||||
The 'wanpipemon' utility operates in two modes.
|
||||
|
||||
Local debugging:
|
||||
The 'wanpipemon' utility is located on the same
|
||||
machine as the WANPIPE card.
|
||||
|
||||
Thus, the wanpipemon utility needs only the
|
||||
interface name (eg: wp1_fr16) to reach the driver.
|
||||
|
||||
/usr/sbin/wanpipemon -i wp1_fr16 -c xm
|
||||
|
||||
|
||||
Remote debugging:
|
||||
The 'wanpipemon' utility is located on a network
|
||||
(LAN or WAN) and must use the UDP protocol to
|
||||
reach the WANPIPE card.
|
||||
|
||||
In this case an IP and UDP addresses must be
|
||||
specified, such that the packet will pass through
|
||||
the WANPIPE driver!
|
||||
|
||||
Meaning a POINTOPOINT address must be used instead
|
||||
of the LOCAL IP address.
|
||||
|
||||
The UDP port was specified in WANPIPE configuration
|
||||
file. (Default=9000)
|
||||
|
||||
/usr/sbin/wanpipemon -i 201.1.1.2 -u 9000 -c xm
|
||||
|
||||
|
||||
GUI Mode Operation
|
||||
==================
|
||||
|
||||
The GUI mode is based on ncurses libraries, thus it
|
||||
will work both in Terminal or Xwindows mode.
|
||||
|
||||
/usr/sbin/wanpipemon -g
|
||||
|
||||
Without any other arguments the GUI will offer a list
|
||||
of network interfaces, for local debugging, or will
|
||||
ask for an IP/UDP address, for remote debugging.
|
||||
|
||||
Use menu's to navigate through available commands.
|
||||
|
||||
|
||||
|
||||
Common Statistics
|
||||
=================
|
||||
|
||||
|
||||
Modem Status (-c xm):
|
||||
|
||||
(wanpipemon -i if_name -c xm)
|
||||
|
||||
Must be DCD=HIGH and CTS=HIGH if not there is
|
||||
ether a cable problem or the sync line is
|
||||
not turned ON.
|
||||
|
||||
Comm Error Stats (-c sc):
|
||||
|
||||
(wanpipemon -i if_name -c sc)
|
||||
|
||||
Check for CRC and Abort errors. If errors
|
||||
are incrementing, there is a line issue.
|
||||
|
||||
Possible reasons: CSU/DSU misconfiguration
|
||||
on local or remote side.
|
||||
|
||||
Noisy/Bad line.
|
||||
|
||||
|
||||
Line trace (-c tr):
|
||||
|
||||
(wanpipemon -i if_name -c tr)
|
||||
|
||||
Make sure thare are incoming and outgoing frames.
|
||||
|
||||
If frames are outgoing and none incoming:
|
||||
|
||||
Frame relay: Check signalling (ANSI, LMI)
|
||||
|
||||
Make sure ISP uses IETF or CISCO
|
||||
data encapsulation.
|
||||
|
||||
Other prot: Possible CRC errors in TX
|
||||
direction. Contact your ISP.
|
||||
|
||||
|
||||
If frames are both incoming and outgoing but
|
||||
protocol is still down:
|
||||
|
||||
Run trace in Interpreted mode (-c ti) and
|
||||
make sure that the incoming protocol is
|
||||
indeed the one you are configured for.
|
||||
|
||||
|
||||
Wanpipe Kernel Messages
|
||||
|
||||
/usr/sbin/wanrouter messages
|
||||
or
|
||||
tail -f /var/log/messages
|
||||
|
||||
All line/protocol events will be displayed in
|
||||
the kernel logs.
|
|
@ -0,0 +1,161 @@
|
|||
WANPIPE ADCCP LAPB API Support
|
||||
==============================
|
||||
|
||||
|
||||
Author: Nenad Corbic <ncorbic@sangoma.com>
|
||||
|
||||
|
||||
|
||||
Pre requisites
|
||||
--------------
|
||||
|
||||
1. A Linux kernel source must be available.
|
||||
Usually in /usr/src/linux directory.
|
||||
|
||||
Furthermore, the linux source version must
|
||||
match the currently running image.
|
||||
|
||||
i.e. Output of 'uname -r'
|
||||
must match the source version
|
||||
number in /usr/src/linux/Makefile.
|
||||
|
||||
Note: The Setup installation script checks
|
||||
for this condition and will take
|
||||
appropriate steps to resolve the
|
||||
name mismatch.
|
||||
|
||||
|
||||
|
||||
|
||||
Installing WANPIPE with ADCCP support
|
||||
-------------------------------------
|
||||
|
||||
The ADCCP support is not installed by default
|
||||
during WANPIPE installation process.
|
||||
|
||||
To enable ADCCP support install WANPIPE using
|
||||
the --protocol option:
|
||||
|
||||
./Setup install --protocol=ADCCP
|
||||
|
||||
OR
|
||||
|
||||
Select desired protocols under the
|
||||
CUSTOM driver compilation option:
|
||||
(part of ./Setup install)
|
||||
|
||||
After successful installation proceed to
|
||||
configure you ADCCP card using /usr/sbin/wancfg
|
||||
GUI configurator.
|
||||
|
||||
|
||||
Installation Verification
|
||||
-------------------------
|
||||
|
||||
Run wanpipe hardware probe to
|
||||
make sure that the kernel modules
|
||||
are working fine:
|
||||
|
||||
Run: wanrouter hwprobe
|
||||
|
||||
|
||||
In case of error:
|
||||
-----------------
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
Configuring ADCCP
|
||||
-----------------
|
||||
|
||||
Run: /usr/sbin/wancfg
|
||||
|
||||
1. Create new device
|
||||
|
||||
2. Select wanpipe1
|
||||
|
||||
3. Protocol Section
|
||||
Select Protocol: ADCCP Protocol
|
||||
|
||||
4. Hardware Section
|
||||
Select Probe Hardware
|
||||
Select your adapter PRI port.
|
||||
|
||||
Specify LAPB Parameters
|
||||
|
||||
Specify DTE/DCE
|
||||
|
||||
Specify HDLC Station Address
|
||||
|
||||
5. Interface Section
|
||||
Specify interface name.
|
||||
(Leave it default)
|
||||
|
||||
6. End of configuration, exit and save
|
||||
|
||||
|
||||
|
||||
Start ADCCP card
|
||||
----------------
|
||||
|
||||
Run: wanrouter start
|
||||
|
||||
|
||||
In case of errors:
|
||||
------------------
|
||||
Run: wanrouter messages
|
||||
|
||||
It will display kernel error
|
||||
messages.
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
Startup Confirmation
|
||||
--------------------
|
||||
|
||||
Run: wanrouter messages
|
||||
|
||||
Confirm that "Starting ADCCP Protocol!" message exist
|
||||
|
||||
|
||||
|
||||
Custom API Application
|
||||
----------------------
|
||||
|
||||
A sample API application exists in
|
||||
/etc/wanpipe/api/x25 directory.
|
||||
|
||||
To compile it run: make
|
||||
|
||||
To run it run: ./hdlc_client wanpipe1 <ifname> write_enable
|
||||
|
||||
Where <ifname> is the name of
|
||||
your interface. If you left it default
|
||||
it would be:
|
||||
|
||||
./hdlc_client wanpipe1 wp1adccp write_enable
|
||||
|
||||
|
||||
The write_enable flag enables tx of packets,
|
||||
if the option is ommited the application will
|
||||
only receive.
|
||||
|
||||
Use this app as a building block for you custom
|
||||
APP.
|
||||
|
||||
|
||||
Further Info
|
||||
------------
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
WANPIPE ADSL Support
|
||||
====================
|
||||
|
||||
|
||||
Author: Nenad Corbic <ncorbic@sangoma.com>
|
||||
|
||||
|
||||
Current WANPIPE Package
|
||||
-----------------------
|
||||
|
||||
Location: ftp.sangoma.com/linux/current_wanpipe
|
||||
|
||||
Package: Choose the current latest
|
||||
eg: wanpipe-beta7-2.3.0.tgz (or greater)
|
||||
|
||||
Changes: README
|
||||
|
||||
|
||||
|
||||
Pre requisites
|
||||
--------------
|
||||
|
||||
1. A Linux kernel source must be available.
|
||||
Usually in /usr/src/linux directory.
|
||||
|
||||
Furthermore, the linux source version must
|
||||
match the currently running image.
|
||||
|
||||
i.e. Output of 'uname -r'
|
||||
must match the source version
|
||||
number in /usr/src/linux/Makefile.
|
||||
|
||||
Note: The Setup installation script checks
|
||||
for this condition and will take
|
||||
appropriate steps to resolve the
|
||||
name mismatch.
|
||||
|
||||
|
||||
|
||||
|
||||
Installing WANPIPE with ADSL support
|
||||
-----------------------------------
|
||||
|
||||
The ADSL support is installed by default
|
||||
during WANPIPE installation process.
|
||||
|
||||
./Setup install
|
||||
|
||||
Follow the Setup installation script and choose
|
||||
all DEFAULT options.
|
||||
|
||||
After successful installation proceed to
|
||||
configure the card for ADSL protocol /usr/sbin/wancfg
|
||||
GUI configurator.
|
||||
|
||||
|
||||
For full installation instructions please refer to
|
||||
ftp.sangoma.com/linux/current_wanpipe/README-1.install.
|
||||
|
||||
|
||||
|
||||
Installation Verification
|
||||
-------------------------
|
||||
|
||||
Run wanpipe hardware probe to
|
||||
make sure that the kernel modules
|
||||
are working fine:
|
||||
|
||||
Run: wanrouter hwprobe
|
||||
|
||||
|
||||
In case of error:
|
||||
-----------------
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
|
||||
Configuring ADSL
|
||||
----------------
|
||||
|
||||
Run: /usr/sbin/wancfg
|
||||
|
||||
1. Create new device
|
||||
|
||||
2. Select wanpipe1
|
||||
|
||||
3. Protocol Section
|
||||
Select Protocol: ADSL Protocol
|
||||
|
||||
4. Hardware Section
|
||||
Select Probe Hardware
|
||||
Select your S518 adapter.
|
||||
|
||||
Encapsulation Mode (ATM):
|
||||
Bridged Ethernet LLC over ATM: (PPPoE)
|
||||
Bridged Ethernet VC over ATM
|
||||
Classical IP LLC over ATM
|
||||
Router IP VC over ATM
|
||||
PPP LLC over ATM
|
||||
PPP VC over ATM: (PPPoA)
|
||||
|
||||
ATM Auto Configuration Option:
|
||||
If set to yes:
|
||||
ADSL driver will autodetect VPI/VCI
|
||||
values on ADSL line.
|
||||
|
||||
If set to no:
|
||||
Manually set the VPI and VCI
|
||||
|
||||
|
||||
Note: Use the auto-configuration only if you
|
||||
don't konw your VPI/VCI numbers.
|
||||
|
||||
ADSL Watchdog:
|
||||
Enable adsl watchdog, that will monitor the
|
||||
line using ATM OAM Loopback requests, every
|
||||
10 seconds.
|
||||
|
||||
If 4 consecutive requests are not responded
|
||||
to, the ADSL line will be re-trained.
|
||||
|
||||
If the remote side doesn't support ATM OAM
|
||||
loopback protocol, the Watchdog will
|
||||
automatically turn off !
|
||||
|
||||
Leave the rest of the options DEFAULT
|
||||
|
||||
|
||||
5. Interface Section
|
||||
|
||||
Specify interface name.
|
||||
(Leave it default)
|
||||
|
||||
Operation Mode:
|
||||
PPPoE: This interface will be used by the PPPoE
|
||||
daemon, thus no ip information is needed.
|
||||
|
||||
WANPIPE: This interface will be used by IP or Ethernet
|
||||
layer, thus IP information is required.
|
||||
|
||||
PAP:
|
||||
Enable PPP PAP authentication (PPPoA only)
|
||||
CHAP:
|
||||
Enable PPP CHAP authenticaiton (PPPoA only)
|
||||
USERID:
|
||||
User id used for PPP authentication (PPPoA only)
|
||||
PASSWD:
|
||||
User password used for PPP auth. (PPPoA only)
|
||||
|
||||
|
||||
DYN_INTR_CFG: Enable dynamic IP addressing (PPPoA only)
|
||||
If enabled set, all IP addresses to 0.0.0.0
|
||||
|
||||
IP Address Setup: (WANPIPE mode only)
|
||||
|
||||
Specify your telco supplied IP addresses
|
||||
|
||||
DYN_INTR_CFG: Enable dynamic IP addressing (PPPoA only)
|
||||
If enabled set, all IP addresses to 0.0.0.0
|
||||
|
||||
|
||||
6. End of configuration, exit and save
|
||||
|
||||
|
||||
For full configuration instructions please refer to
|
||||
ftp.sangoma.com/linux/current_wanpipe/README-2.config
|
||||
|
||||
|
||||
|
||||
Start ADSL protocol
|
||||
-------------------
|
||||
|
||||
Run: wanrouter start
|
||||
|
||||
|
||||
In case of errors:
|
||||
------------------
|
||||
Run: wanrouter messages
|
||||
|
||||
It will display kernel error
|
||||
messages.
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
For full operation instructions please refer to
|
||||
ftp.sangoma.com/linux/current_wanpipe/README-3.operation
|
||||
|
||||
|
||||
Startup Confirmation
|
||||
--------------------
|
||||
|
||||
Run: wanrouter messages
|
||||
|
||||
Make sure no error messages are displayed.
|
||||
|
||||
Confirm the Link state: Link connected
|
||||
Note the down and up stream baud rates.
|
||||
|
||||
eg: ADSL Link connected (Down 1728 kbps, Up 384 kbps)
|
||||
|
||||
Check for any error events.
|
||||
|
||||
|
||||
For full debugging instructions please refer to
|
||||
ftp.sangoma.com/linux/current_wanpipe/README-4.debugging
|
||||
|
||||
|
||||
Further Info
|
||||
------------
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Configuring WANPIPE ADSL Drivers for PPPoE
|
||||
------------------------------------------
|
||||
|
||||
1.Run /usr/sbin/wancfg
|
||||
|
||||
2.Select ADSL Protocol
|
||||
|
||||
3.Select Hardware Option
|
||||
|
||||
4.Probe for ADSL card (S518) and select it
|
||||
|
||||
5.Select EncapMode=ETH_LLC_OA
|
||||
ie: Bridged Ethernet LLC over ATM encapsulation
|
||||
|
||||
6.If you have ATM VPI/VCI information, disable ATM auto
|
||||
configuration and specify the VPI/VCI combination.
|
||||
Otherwise, try to autodetect the VPI/VCI numbers.
|
||||
|
||||
7.Select Network Interface Setup
|
||||
|
||||
8.Specify PPPoE operation mode
|
||||
|
||||
9.Save and Exit
|
||||
|
||||
10.Start Wanpipe: wanrouter start
|
||||
|
||||
|
||||
The next step is to configure PPPoE over the newly created WANPIPE interface.
|
||||
|
||||
1. Download PPPoE utility from sangoma web site
|
||||
ftp.sangoma.com/linux/utilities/rp-pppoe-3.4.tar.gz
|
||||
|
||||
2. Untar the rp-pppoe-3.4.tar.gz in tmp/ directory
|
||||
Read the README file
|
||||
|
||||
3. Install rp-pppoe: ./go
|
||||
Configure rp-pppoe: adsl_setup
|
||||
|
||||
Use the WANPIPE network interface as the Ethernet
|
||||
interface connected to a modem. Specify username and
|
||||
password as well as DNS info.
|
||||
|
||||
4. Start PPPoE: adsl-start
|
||||
|
||||
5. Read /var/log/messages for connection status.
|
||||
eg: tail -f /var/log/messages
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Configurig WANPIPE ADSL Drives for PPPoA
|
||||
----------------------------------------
|
||||
|
||||
|
||||
1.Run /usr/sbin/wancfg
|
||||
|
||||
2.Select ADSL Protocol
|
||||
|
||||
3.Select Hardware Option
|
||||
|
||||
4.Probe for ADSL card and select it
|
||||
|
||||
5.Select EncapMode=PPP_VC_OA
|
||||
ie: PPP VC over ATM encapsulation
|
||||
|
||||
6.If you have ATM VPI/VCI information,
|
||||
disable ATM auto configuration and specify
|
||||
the VPI/VCI combination.
|
||||
Otherwise, try to autodetect the VPI/VCI numbers.
|
||||
|
||||
7.Select Network Interface Setup
|
||||
|
||||
8.Specify WANPIPE operation mode
|
||||
|
||||
9.Enable PAP or CHAP Authentication if Required
|
||||
|
||||
10. Specify PPP user name and password if PAP or CHAP
|
||||
has been enabled.
|
||||
|
||||
11. IP address setup: By default, the IP addresses are
|
||||
dynamically negotiated by the PPP
|
||||
protocol.
|
||||
|
||||
DYN_INTR_CFG: Enables dynamic PPP ip addressing
|
||||
|
||||
Set all ip addresses to 0.0.0.0
|
||||
Set netmsak ip address to 255.255.255.255
|
||||
|
||||
|
||||
14. Configure Startup Scripts (Optional)
|
||||
|
||||
When pppoa interface negotiates new IP address
|
||||
kernel will envoke a user space program
|
||||
to handle any usr space tasks associated with
|
||||
the new interface.
|
||||
|
||||
Thus proceed to create a STARTUP, read the
|
||||
wancfg/wancfg_adv documentation.
|
||||
|
||||
|
||||
13.Save and Exit
|
||||
|
||||
14.Start Wanpipe: wanrouter start
|
|
@ -0,0 +1,160 @@
|
|||
AFT Channelized Operaton
|
||||
------------------------
|
||||
|
||||
AFT Channelized Support is used mainly to support soft
|
||||
PBX or IVR systems. It can also be used to support
|
||||
non standard framing, for example 13 bit monosych.
|
||||
|
||||
On the A101 and A102 cards you can mix voice
|
||||
applications with standard WANPIPE(R) routing.
|
||||
|
||||
So you can configure, say:
|
||||
|
||||
Timeslots 1-16
|
||||
Operation: HDLC Mode
|
||||
Usedby: WANPIPE routing of IP over Frame
|
||||
Relay
|
||||
|
||||
Timeslots 17-23
|
||||
Operation: Transparent (Raw) Mode
|
||||
Usedby Voice channels hooked to Asterisk PBX
|
||||
|
||||
Timeslot 24
|
||||
Operation: HDLC Mode
|
||||
Usedby: Asterisk PRI signaling channel
|
||||
|
||||
|
||||
|
||||
Setup wanpipe into timeslot channelized mode, where each
|
||||
timeslot has a dedicated network interface. A custom
|
||||
application uses a network interface to read/write
|
||||
data directly to a specific timeslot.
|
||||
|
||||
CONFIGURATION
|
||||
=============
|
||||
|
||||
Using you wancfg configurator
|
||||
|
||||
1. Select AFT HDLC protocol
|
||||
|
||||
2. Hardware Setup
|
||||
Do a hardware probe and find an AFT card
|
||||
|
||||
Leave everything else default
|
||||
|
||||
3. T1/E1 Setup
|
||||
Configure based on you isp info.
|
||||
|
||||
|
||||
3. Interface Setup
|
||||
|
||||
If T1 specify up to 24 interfaces
|
||||
If E1 specify up to 32 interfaces
|
||||
|
||||
For each interface:
|
||||
|
||||
Interface Name: Leave default
|
||||
(or specify name)
|
||||
|
||||
Operation Mode: VOIP - Iface Used by Asterisk
|
||||
API - Iface Used by custom application
|
||||
WANPIPE - Iface Used by IP Stack
|
||||
|
||||
Note: If WANPIPE mode selected choose a
|
||||
Protocol/IP and configure them
|
||||
accordingly.
|
||||
|
||||
eg: Protocol: MP_FR (Frame Relay)
|
||||
IP Address Setup
|
||||
|
||||
Bound Channels: (Select one or more timeslots)
|
||||
eg: 1 #Timeslot number one
|
||||
1-5 #Timeslots one to five
|
||||
1-5.10-15 #Timeslots one to five
|
||||
#and ten to fifteen
|
||||
|
||||
HDLC: (To enable disable HDLC engine on this
|
||||
interface)
|
||||
YES: HDLC mode enabled
|
||||
NO: Transparent (Bitstreaming/Raw) Mode enabled
|
||||
|
||||
MTU:
|
||||
Set the MTU value appropriate for this
|
||||
interface:
|
||||
|
||||
eg: Voice Applications: Set to 10 or less.
|
||||
Wanpipe: Set to 1500
|
||||
|
||||
|
||||
Leave all other options default
|
||||
|
||||
4. When you finish interface configuration
|
||||
proceed to exit
|
||||
|
||||
|
||||
OPERATION
|
||||
=========
|
||||
|
||||
1. Start wanpipe
|
||||
|
||||
eg: wanrouter start
|
||||
|
||||
Note: You will see up to 24/32 interfaces
|
||||
configured:
|
||||
eg: ifconfig
|
||||
|
||||
|
||||
API CUSTOM APPLICATIONS
|
||||
========================
|
||||
|
||||
Use a sample app in /etc/wanpipe/api/aft
|
||||
|
||||
You can run the app directly over each interface and
|
||||
read/write custom data to a specific timeslot.
|
||||
|
||||
The interfaces that have HDLC enabled, will
|
||||
tx/rx HDLC frames.
|
||||
|
||||
The interface that have HDLC disabled, will
|
||||
tx/rx raw bits with no encapsulation.
|
||||
|
||||
|
||||
Run: ./aft_api
|
||||
|
||||
Refer to api options below:
|
||||
|
||||
AFT API USAGE
|
||||
|
||||
|
||||
aft_api <options> <extra options>
|
||||
|
||||
<options>:
|
||||
-i <ifname> #interface name
|
||||
-c <card name> #card name
|
||||
-r #read enable
|
||||
-w #write eable
|
||||
|
||||
<extra options>
|
||||
-txcnt <digit> #number of tx packets (Dflt: 1)
|
||||
-txsize <digit> #tx packet size (Dflt: 10)
|
||||
-txdelay <digit> #delay in sec after each tx packet (Dflt: 0)
|
||||
-txdata <digit> #data to tx <1-255>
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
#Enable read and write on wp1aft interface
|
||||
|
||||
./aft_api -c wanpipe1 -i wp1aft -r -w -txsize 100 -txcnt 1 -verbose
|
||||
|
||||
#Receive Only
|
||||
|
||||
./aft_api -c wanpipe1 -i wp1aft -r -verbose
|
||||
|
||||
|
||||
|
||||
ASTERISK
|
||||
========
|
||||
|
||||
Please refer to README.Asterisk
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
AFT Channelized Operation
|
||||
------------------------
|
||||
|
||||
AFT Channelized Support is used to support multi-timeslot
|
||||
HDLC hub implementations (hubs for remote sub-DS1 nodes)
|
||||
or soft PBX or IVR systems. It can also be used to support
|
||||
non-standard framing, for example 13 bit monosynch.
|
||||
|
||||
On the A101 and A102 cards you can mix voice
|
||||
applications with standard WANPIPE(R) routing.
|
||||
|
||||
So you can configure, say:
|
||||
|
||||
Timeslots 1-16
|
||||
Operation: HDLC Mode
|
||||
Used by: WANPIPE routing of IP over Frame
|
||||
Relay
|
||||
|
||||
Timeslots 17-23
|
||||
Operation: Transparent (Raw) Mode
|
||||
Used by Voice channels hooked to Asterisk PBX
|
||||
|
||||
Timeslot 24
|
||||
Operation: HDLC Mode
|
||||
Used by: Asterisk PRI signaling channel
|
||||
|
||||
|
||||
Setup wanpipe into timeslot channelized mode, where each
|
||||
timeslot or timeslot group has a dedicated network interface.
|
||||
A custom API is available to read/write data to a network
|
||||
interface.
|
||||
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
=============
|
||||
|
||||
Using the wancfg configurator:
|
||||
|
||||
1. Select AFT HDLC protocol
|
||||
|
||||
2. Hardware Setup
|
||||
Do a hardware probe and find an AFT card
|
||||
|
||||
Leave everything else default
|
||||
|
||||
3. T1/E1 Setup
|
||||
Configure based on your telco info.
|
||||
|
||||
|
||||
3. Interface Setup
|
||||
|
||||
If T1 specify up to 24 interfaces
|
||||
If E1 specify up to 31 interfaces
|
||||
|
||||
For each interface:
|
||||
|
||||
Interface Name: Leave default
|
||||
(or specify name)
|
||||
|
||||
Operation Mode: VOIP - Iface Used by Asterisk
|
||||
API - Iface Used by custom application
|
||||
WANPIPE - Iface Used by IP Stack
|
||||
|
||||
Note: If WANPIPE mode selected choose a
|
||||
Protocol/IP and configure them
|
||||
accordingly.
|
||||
|
||||
e.g.: Protocol: MP_FR (Frame Relay)
|
||||
IP Address Setup
|
||||
|
||||
Bound Channels: (Select one or more timeslots)
|
||||
e.g.: 1 #Timeslot number one
|
||||
1-5 #Timeslots one to five
|
||||
1-5.10-15 #Timeslots one to five
|
||||
#and ten to fifteen
|
||||
|
||||
HDLC: (To enable disable HDLC engine on this
|
||||
interface)
|
||||
YES: HDLC mode enabled (must be enabled for WANPIPE routing)
|
||||
NO: Transparent (Bitstreaming/Raw) Mode enabled
|
||||
|
||||
MTU:
|
||||
Set the MTU value appropriate for this
|
||||
interface:
|
||||
|
||||
e.g.: Voice Applications: Set to 10 or less.
|
||||
Wanpipe: Set to 1500
|
||||
|
||||
|
||||
Leave all other options default.
|
||||
|
||||
4. When you finish interface configuration
|
||||
proceed to exit.
|
||||
|
||||
|
||||
|
||||
|
||||
OPERATION
|
||||
=========
|
||||
|
||||
1. Start wanpipe
|
||||
|
||||
e.g.: wanrouter start
|
||||
|
||||
Note: You will see up to 24/32 interfaces
|
||||
configured:
|
||||
e.g.: ifconfig
|
||||
|
||||
|
||||
|
||||
|
||||
API CUSTOM APPLICATIONS
|
||||
========================
|
||||
|
||||
Use a sample app in /etc/wanpipe/api/aft
|
||||
|
||||
You can run the app directly over each interface and
|
||||
read/write custom data to a specific timeslot.
|
||||
|
||||
The interfaces that have HDLC enabled, will
|
||||
tx/rx HDLC frames.
|
||||
|
||||
The interface that have HDLC disabled, will
|
||||
tx/rx raw bits with no encapsulation.
|
||||
|
||||
|
||||
Run: ./aft_api
|
||||
|
||||
Refer to api options below:
|
||||
|
||||
AFT API USAGE
|
||||
|
||||
|
||||
aft_api <options> <extra options>
|
||||
|
||||
<options>:
|
||||
-i <ifname> #interface name
|
||||
-c <card name> #card name
|
||||
-r #read enable
|
||||
-w #write enable
|
||||
|
||||
<extra options>
|
||||
-txcnt <digit> #number of tx packets (Dflt: 1)
|
||||
-txsize <digit> #tx packet size (Dflt: 10)
|
||||
-txdelay <digit> #delay in sec after each tx packet (Dflt: 0)
|
||||
-txdata <digit> #data to tx <1-255>
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
#Enable read and write on wp1aft interface
|
||||
|
||||
./aft_api -c wanpipe1 -i wp1aft -r -w -txsize 100 -txcnt 1 -verbose
|
||||
|
||||
#Receive Only
|
||||
|
||||
./aft_api -c wanpipe1 -i wp1aft -r -verbose
|
||||
|
||||
|
||||
|
||||
ASTERISK
|
||||
========
|
||||
|
||||
Please refer to ftp.sangoma.com/linux/doc/README.asterisk
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
AFT FIRMWARE UPDATE
|
||||
===================
|
||||
|
||||
1) Make sure WANPIPE is installed on your
|
||||
system, via:
|
||||
|
||||
./Setup install
|
||||
|
||||
|
||||
2) Change directory to
|
||||
|
||||
wanpipe/util/wan_aftup
|
||||
|
||||
Where wanpipe/ is directory created
|
||||
on wanpipe install.
|
||||
|
||||
|
||||
3) Read the README file :)
|
||||
|
||||
|
|
@ -0,0 +1,458 @@
|
|||
Asterisk Open PBC/IVR Project using the Sangoma A101 and A102 cards
|
||||
===================================================================
|
||||
|
||||
Alex Feldman: Mar 2005
|
||||
Nenad Corbic:
|
||||
|
||||
WANPIPE supports the Asterisk Open PBX/IVR project through an interface
|
||||
of the Zaptel family of hardware devices. These devices share a common
|
||||
driver suite, called the ZAPATA Telephony Driver Suite (zaptel).
|
||||
|
||||
|
||||
IMPORTANT
|
||||
---------
|
||||
Please read the APPENDIX for IMPORTANT INFO
|
||||
|
||||
|
||||
|
||||
ASTERISK / ZAPTEL Installation
|
||||
-------------------------------
|
||||
|
||||
First install:
|
||||
zaptel, zapata, libpri and asterisk
|
||||
software on your system.
|
||||
|
||||
The Asterisk distributions can be found at http://www.asterisk.org.
|
||||
|
||||
1. Download the LATEST sources from http://www.asterisk.org;
|
||||
|
||||
2. Untar zaptel, libpri and asterisk source
|
||||
in /usr/src directory
|
||||
|
||||
3. Proceed with ASTERISK/ZAPTEL installation as per
|
||||
Asterisk instructions
|
||||
|
||||
|
||||
Note:
|
||||
Zaptel kernel drivers must compiled and
|
||||
installed BEFORE loading WANPIPE drivers.
|
||||
|
||||
|
||||
|
||||
WANPIPE Releases
|
||||
----------------
|
||||
|
||||
2.3.3: Latest Wanpipe Release
|
||||
All the NEW features are for A104 Card ONLY
|
||||
|
||||
o New channelized TDMV Driver for A104 Card
|
||||
|
||||
Voice data is channelized and grouped into
|
||||
8 byte chunks in HARDWARE. Each voice
|
||||
channel is then DMAed directly into the ZAPTEL
|
||||
buffers. Thus there is ZERO copy from HARDWARE
|
||||
to ZAPTEL, resulting in better performance and
|
||||
scalability.
|
||||
|
||||
o New DCHAN PRI Hardware HDLC support (A104 Only)
|
||||
|
||||
Instead of using ZAPTEL HDLC engines in software,
|
||||
WANPIPE drivers use HARDWARE HDLC engine to
|
||||
handle PRI traffic. The HDLC frames are
|
||||
then passed directly into the LIBPRI, resulting
|
||||
in better performance and scalability.
|
||||
|
||||
o New TDMV API (A104 Only)
|
||||
|
||||
Customers that develop Voice Applications in User Space, can now develop using Channelized TDMV API.
|
||||
|
||||
The TDMV API works in the same way as standard HDLC API.
|
||||
Application creates a socket to a network interface and
|
||||
uses standard system calls to read and write.
|
||||
However, data received from the TDMV API socket, will be
|
||||
in 8,16,32 or 63 byte CHUNKS for each configured timeslot.
|
||||
|
||||
Thus for full T1 1-23 voice channels the rx data would
|
||||
look like:
|
||||
__________________________________
|
||||
| 8bytes | 8 | | ... | 8 |
|
||||
----------------------------------
|
||||
Slot 1 2 3 23
|
||||
|
||||
The DCHAN PRI HDLC frames would be received as OOB messages
|
||||
on the same socket.
|
||||
|
||||
OR
|
||||
|
||||
The DCHAN PRI HDLC frames could be received using another
|
||||
socket that is connected to a network interface that is
|
||||
bound to channel 24.
|
||||
|
||||
|
||||
2.3.2: Stable Wanpipe TDMV Release
|
||||
|
||||
o The ORIGINAL TDMV driver for both A101/2 and A104 cards.
|
||||
TDMV Driver has been optimized for best Echo cancel
|
||||
performance.
|
||||
|
||||
This driver has been fully tested in the field and is
|
||||
considered stable.
|
||||
|
||||
|
||||
|
||||
|
||||
WANPIPE Installation for Asterisk
|
||||
---------------------------------
|
||||
|
||||
1. Download the LATEST Wanpipe 2.3.2 Release or Greater!
|
||||
|
||||
Note: Wanpipe does not support Asterisk in releases
|
||||
LOWER than 2.3.2!
|
||||
|
||||
ftp.sangoma.com/linux/current_wanpipe
|
||||
|
||||
|
||||
2. Untar wanpipe release in /usr/src/ directory
|
||||
|
||||
eg: tar xvfz wanpipe-beta3-2.3.2.tgz
|
||||
|
||||
|
||||
3. Run ./Setup install
|
||||
|
||||
Proceed with installation choose YES for each option.
|
||||
|
||||
IMPORTANT:
|
||||
Under compilation mode: select CUSTOM
|
||||
|
||||
Then select: DEF :for default protocols
|
||||
TDM :for TDM Voice asterisk support
|
||||
|
||||
Enable TDMV_DCHAN option for Hardware HDLC for
|
||||
DCHAN PRI.
|
||||
|
||||
This option will also PATCH the ZAPTEL driver.
|
||||
Thus, ZAPTEL MUST be recompiled and installed
|
||||
after the ./Setup is completed.
|
||||
|
||||
Proceed to compile wanpipe drivers.
|
||||
|
||||
4. To confirm successful installation run:
|
||||
|
||||
wanrouter hwprobe
|
||||
|
||||
Confirm that Sangoma cards have been found.
|
||||
|
||||
Note:
|
||||
Zaptel kernel drivers must compiled and
|
||||
installed BEFORE loading WANPIPE drivers.
|
||||
|
||||
|
||||
WANPIPE Configuration for the A100 series of cards
|
||||
--------------------------------------------------
|
||||
|
||||
You can use the A101 or A102 cards for both data and voice. The
|
||||
following describes how to configure the Asterisk system for
|
||||
voice, with an auxiliary data interface, if needed.
|
||||
|
||||
1. Run the configuration utility wancfg.
|
||||
|
||||
/usr/sbin/wancfg
|
||||
|
||||
Hardware Setup:
|
||||
Select Hardware: AFT
|
||||
|
||||
T1/E1 CSU/DSU Setup can be configured via
|
||||
"Advanced Physical Medium Config"
|
||||
|
||||
If all the 24 (T1) or 30 (E1) timeslots will
|
||||
be used by Asterisk then there is no need to
|
||||
configure the T1/E1 Channelization.
|
||||
|
||||
If less than the full span is used by Asterisk,
|
||||
set the channel span in
|
||||
"Advanced Timeslot Groups Configuration"
|
||||
|
||||
Protocol Setup:
|
||||
Select Protocol: TDM VOICE
|
||||
No other options
|
||||
|
||||
Interface Setup:
|
||||
Select SPAN Number: 1-24
|
||||
The SPAN usually starts with 1
|
||||
No other options
|
||||
|
||||
|
||||
|
||||
2. DCHAN Configuration (A104 Card Only):
|
||||
|
||||
Release : beta1-2.3.3 or greater.
|
||||
Firmware Version: V.10
|
||||
|
||||
Currently DCHAN is not supported in wancfg,
|
||||
thus one has to add it manually to wanpipe#.conf file.
|
||||
|
||||
Add it under the SPAN configuration.
|
||||
.
|
||||
.
|
||||
TDMV_SPAN=1
|
||||
TDMV_DCHAN=24
|
||||
.
|
||||
.
|
||||
|
||||
Note: TDMV_DCHAN value is ALWAYS from (1-24).
|
||||
(Don't confuse with Asterisk configuration
|
||||
that uses values greater than 24 for DCHAN
|
||||
specification)
|
||||
|
||||
3. A102 TE1 Clock Synchronization (A102 Card Only):
|
||||
|
||||
Release : beta7-2.3.2 or greater.
|
||||
Firmware Version: V.24
|
||||
|
||||
This option is NOT supported in wancfg, thus
|
||||
one has to add it manually to wanpipe#.conf file.
|
||||
|
||||
TE1 Clock synchronization is used to propagate
|
||||
a single clock source throughout the
|
||||
TE1 network.
|
||||
|
||||
wanpipe1->Port A-> Normal Mode: Receives T1 Clock from Telco
|
||||
wanpipe2->Port B-> Master Mode: Transmits the SAME T1
|
||||
Clock as a master source.
|
||||
|
||||
In order to enable this option on wanpipe2:
|
||||
Add FE_REF_CLOCK option under the "TE_CLOCK" option.
|
||||
.
|
||||
.
|
||||
TE_CLOCK = MASTER
|
||||
FE_REF_CLOCK = LINE
|
||||
.
|
||||
.
|
||||
Note: That TE_CLOCK must be set as MASTER
|
||||
The Clock source is the Port A LINE.
|
||||
|
||||
IMPORTANT: When start and stopping devices
|
||||
START: Master(wanpipe1) then Slave(wanpipe2)
|
||||
STOP: Slave(wanpipe2) then Master(wanpipe1)
|
||||
|
||||
If the wanpipe1 device is stopped, the
|
||||
wanpipe2 device, that is using the clock
|
||||
from wanpipe1, will loose its clock thus
|
||||
resulting in unpredictable operation.
|
||||
|
||||
|
||||
Channelization Notes:
|
||||
--------------------
|
||||
|
||||
If you re using PRI mode, channel 24 must be included in the
|
||||
"Timeslots in Group" list for the Asterisk T1 span, and channel
|
||||
16 for the Asterisk E1 span.
|
||||
|
||||
For the non-Asterisk data channels, if any, configure
|
||||
the interface as standard WANPIPE interface,
|
||||
running: Frame Relay, PPP, Cisco HDLC or X.25 with IP or API
|
||||
access.
|
||||
|
||||
|
||||
Zaptel configuration
|
||||
--------------------
|
||||
|
||||
Download the documentation how to configure Zaptel driver from
|
||||
|
||||
(http://www.digium.com/downloads/configuring_zaptel.pdf).
|
||||
|
||||
When configuring the Zaptel driver (/etc/zaptel.conf)
|
||||
|
||||
1) Select the same span configurations as you used for WANPIPE
|
||||
(i.e. LBO, framing, coding parameters).
|
||||
|
||||
Otherwise the Zaptel configuration is completely
|
||||
standard, except that if there are data channels that
|
||||
will be handled by WANPIPE, those channels should be ignored,
|
||||
and not configured as 'nethdlc'.
|
||||
|
||||
2) If you are using multiple WANPIPE devices for Asterisk
|
||||
|
||||
For example, an A102 card might be configured as:
|
||||
|
||||
wanpipe1 and wanpipe2
|
||||
|
||||
then you need to set your starting scripts to start
|
||||
the wanpipes in the same sequence as defined in zaptel.conf.
|
||||
|
||||
Run: wanrouter wanrc
|
||||
|
||||
to set the wanpipe startup order.
|
||||
|
||||
3) If you are using some channels for DATA
|
||||
|
||||
You don't need to set the channel list for this
|
||||
interface under /etc/zaptel.conf because all data will go
|
||||
through the separate WANPIPE driver to the kernel.
|
||||
|
||||
|
||||
|
||||
APPENDIX
|
||||
========
|
||||
|
||||
-------------------------------------------------------------
|
||||
|
||||
1)HOTPLUG Conflicts with WANPIPE
|
||||
===============================
|
||||
|
||||
|
||||
The HOTPLUG Service should be disabled because it
|
||||
conflicts with Wanpipe interface startup.
|
||||
The HOTPLUG can conflict with startup of TDMV drivers.
|
||||
|
||||
Possible Solutions:
|
||||
|
||||
1) Insert wanpipe interface name into the hotplug
|
||||
interface list, and restart hotplug.
|
||||
|
||||
vi /etc/hotplug/net.agent
|
||||
|
||||
Insert wanpipe interface name into
|
||||
the ignore list:
|
||||
|
||||
...ppp*|lo*|w*)
|
||||
|
||||
Where w* relates to all wanpipe interfaces
|
||||
starting with letter "w"
|
||||
|
||||
Restart hotplug agent:
|
||||
|
||||
/etc/init.d/hotplug restart
|
||||
|
||||
2) Remove the Hotplug RPM
|
||||
rpm -qa | grep hotplug
|
||||
rpm -e <hotplug name>
|
||||
|
||||
3) Stop hotplug:
|
||||
/etc/init.d/hotplug stop
|
||||
|
||||
However, you must do this each
|
||||
time you boot up. Thus insert this
|
||||
command in rc.local.
|
||||
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
|
||||
2) Exec "ztcfg" after wanrouter start
|
||||
==================================
|
||||
|
||||
The "ztcfg" tool must be executed before starting
|
||||
asterisk. WANPIPE "wanrouter" script has the capability
|
||||
to execute an external script after "wanrouter start"
|
||||
command is competed.
|
||||
|
||||
The wanrouter looks to /etc/wanpipe/scripts directory
|
||||
for any configured bash scripts.
|
||||
|
||||
1) Create a file called "start" (lower case)
|
||||
|
||||
vi start
|
||||
----------Cut Here----------------
|
||||
#!/bin/sh
|
||||
|
||||
ztcfg -vvvv
|
||||
|
||||
----------Cut Here----------------
|
||||
|
||||
2) Copy the file "start" into /etc/wanpipe/scripts directory.
|
||||
(Note: the file doesn't have to have exec privileges)
|
||||
|
||||
|
||||
The script "start" will execute each time the "wanrouter start"
|
||||
command executes.
|
||||
|
||||
|
||||
Please Refer to README.external_scripts for more info about
|
||||
wanrouter and external scripts.
|
||||
|
||||
|
||||
------------------------------------------------------------
|
||||
|
||||
|
||||
2) Updating FLASH on AFT Cards
|
||||
===========================
|
||||
|
||||
The AFT FLASH update utility is located in:
|
||||
wanpipe/util/wan_aftup directory.
|
||||
|
||||
The same directory contains the latest AFT
|
||||
FLASH Firmware BIN files since the release
|
||||
of the driver.
|
||||
|
||||
The latest AFT Firmware bins are located in
|
||||
ftp.sangoma.com/linux/current_wanpipe/firmware.
|
||||
|
||||
|
||||
To update flash on ANY AFT card do the following:
|
||||
|
||||
1) Make sure you have the latest AFT Firmware BIN
|
||||
The latest file necessary for the current release
|
||||
will be in the wan_aftup/ directory.
|
||||
One can also check the ftp site above.
|
||||
|
||||
The AFT Binary file must reside in wan_aftup/ directory.
|
||||
|
||||
2) Make sure that wanpipe drivers are NOT Loaded
|
||||
lsmod | grep wanpipe
|
||||
|
||||
3) Run ./update_aft_firm.sh
|
||||
|
||||
Specify interface name that corresponds to the
|
||||
AFT card.
|
||||
|
||||
Specify the latest AFT Firmware version
|
||||
|
||||
Once the flashing is done, select Y to reload firmware.
|
||||
(This step only reloads flash, not your machine!)
|
||||
|
||||
4) Card is ready for normal operation. (No reboot needed)
|
||||
|
||||
---------------------------------------------------------------
|
||||
|
||||
|
||||
3) Multiple ZAPTEL Releases AND Wanpipe Crashing
|
||||
=============================================
|
||||
|
||||
On systems, where ZAPTEL has been upgraded from old
|
||||
releases, it is possible for a kernel module directory
|
||||
to contain MULTIPLE ZAPTEL drivers.
|
||||
|
||||
Old Zaptel install dir: /lib/modules/$(uname -r)/zaptel
|
||||
|
||||
New Zpatel install dir: /lib/modules/$(uname -r)/misc
|
||||
|
||||
If old zaptel installation was NOT removed, the new installation
|
||||
would NOT overwrite the old kernel modules. In this case
|
||||
the OLD modules would continue to be loaded, even though the
|
||||
new ones were installed.
|
||||
|
||||
Check:
|
||||
|
||||
The check if this condition exists on your machine run:
|
||||
|
||||
modprobe -l | grep zaptel.*o
|
||||
|
||||
If multiple zaptel modules are found
|
||||
the problem must be fixed before starting
|
||||
WANPIPE !!!.
|
||||
|
||||
|
||||
In this scenario, if a customer starts WANPIPE drivers based
|
||||
on NEW ZAPTEL sources, the WANPIPE would CRASH !!!
|
||||
The WANPIPE driver shares structures with ZAPTEL, thus, a
|
||||
result of mismatched structures is a kernel panic.
|
||||
|
||||
|
||||
Solution:
|
||||
|
||||
The solution in this case is to REMOVE the old zaptel modules.
|
||||
rm -rf /lib/modules/$(uname -r)/zaptel
|
||||
depmod -a
|
||||
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
WANPIPE ATM Support
|
||||
===================
|
||||
|
||||
|
||||
Author: Nenad Corbic <ncorbic@sangoma.com>
|
||||
|
||||
|
||||
|
||||
Pre requisites
|
||||
--------------
|
||||
|
||||
1. A Linux kernel source must be available.
|
||||
Usually in /usr/src/linux directory.
|
||||
|
||||
Furthermore, the linux source version must
|
||||
match the currently running image.
|
||||
|
||||
i.e. Output of 'uname -r'
|
||||
must match the source version
|
||||
number in /usr/src/linux/Makefile.
|
||||
|
||||
Note: The Setup installation script checks
|
||||
for this condition and will take
|
||||
appropriate steps to resolve the
|
||||
name mismatch.
|
||||
|
||||
|
||||
|
||||
|
||||
Installing WANPIPE with ATM support
|
||||
-----------------------------------
|
||||
|
||||
The ATM support is installed by default
|
||||
during WANPIPE installation process.
|
||||
|
||||
./Setup install
|
||||
|
||||
Follow the Setup installation script and choose
|
||||
all DEFAULT options.
|
||||
|
||||
After successful installation proceed to
|
||||
configure the card for ATM protocol /usr/sbin/wancfg
|
||||
GUI configurator.
|
||||
|
||||
|
||||
Installation Verification
|
||||
-------------------------
|
||||
|
||||
Run wanpipe hardware probe to
|
||||
make sure that the kernel modules
|
||||
are working fine:
|
||||
|
||||
Run: wanrouter hwprobe
|
||||
|
||||
|
||||
In case of error:
|
||||
-----------------
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
Configuring ATM
|
||||
---------------
|
||||
|
||||
Run: /usr/sbin/wancfg
|
||||
|
||||
1. Create new device
|
||||
|
||||
2. Select wanpipe1
|
||||
|
||||
3. Protocol Section
|
||||
Select Protocol: ATM Protocol
|
||||
|
||||
4. Hardware Section
|
||||
Select Probe Hardware
|
||||
Select your adapter PRI port.
|
||||
|
||||
5. Interface Section
|
||||
|
||||
Select number of PVC you wish to configure
|
||||
(Default=1)
|
||||
|
||||
Specify interface name.
|
||||
(Leave it default)
|
||||
|
||||
Specify ATM VPI, VCI values for that pvc
|
||||
|
||||
Specify ATM Encapsulation Headers:
|
||||
Ethernet over ATM (LLC/VC) (PPPoE)
|
||||
Classical IP over ATM (LLC/VC)
|
||||
|
||||
Specify IP info for pvc
|
||||
|
||||
6. End of configuration, exit and save
|
||||
|
||||
|
||||
|
||||
Start ATM protocol
|
||||
------------------
|
||||
|
||||
Run: wanrouter start
|
||||
|
||||
|
||||
In case of errors:
|
||||
------------------
|
||||
Run: wanrouter messages
|
||||
|
||||
It will display kernel error
|
||||
messages.
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
Startup Confirmation
|
||||
--------------------
|
||||
|
||||
Run: wanrouter messages
|
||||
|
||||
Make sure no error messages are dispalyed.
|
||||
|
||||
Confirm the state of Front End (T1/E1/V35)
|
||||
Confirm the Link state
|
||||
|
||||
Check for any error events.
|
||||
|
||||
|
||||
Further Info
|
||||
------------
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,352 @@
|
|||
WANPIPE T1/E1/V35 Bitstreaming
|
||||
==============================
|
||||
|
||||
|
||||
Author: Nenad Corbic <ncorbic@sangoma.com>
|
||||
|
||||
|
||||
|
||||
Pre requisites
|
||||
--------------
|
||||
|
||||
1. A Linux kernel source must be available.
|
||||
Usually in /usr/src/linux directory.
|
||||
|
||||
Furthermore, the linux source version must
|
||||
match the currently running image.
|
||||
|
||||
i.e. Output of 'uname -r'
|
||||
must match the source version
|
||||
number in /usr/src/linux/Makefile.
|
||||
|
||||
Note: The Setup installation script checks
|
||||
for this condition and will take
|
||||
appropriate steps to resolve the
|
||||
name mismatch.
|
||||
|
||||
|
||||
|
||||
|
||||
Installing WANPIPE with BitStreaming support
|
||||
--------------------------------------------
|
||||
|
||||
The BitStreaming support is NOT installed by default
|
||||
during WANPIPE installation process.
|
||||
|
||||
|
||||
Use the CUSTOM driver compilation
|
||||
option in
|
||||
./Setup install
|
||||
script to enable BITSTRM.
|
||||
|
||||
OR
|
||||
|
||||
use the --protocol option:
|
||||
./Setup install --protocol=BITSTRM
|
||||
|
||||
|
||||
After successful installation proceed to
|
||||
configure the card for BitStreaming protocol
|
||||
/usr/sbin/wancfg GUI configurator.
|
||||
|
||||
|
||||
Installation Verification
|
||||
-------------------------
|
||||
|
||||
Run wanpipe hardware probe to
|
||||
make sure that the kernel modules
|
||||
are working fine:
|
||||
|
||||
Run: wanrouter hwprobe
|
||||
|
||||
|
||||
In case of error:
|
||||
-----------------
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
Configuring BitStreaming
|
||||
------------------------
|
||||
|
||||
Run: /usr/sbin/wancfg
|
||||
|
||||
1. Create new device
|
||||
|
||||
2. Select wanpipe1
|
||||
|
||||
3. Protocol Section
|
||||
Select Protocol: BitStreaming Protocol
|
||||
|
||||
4. Hardware Section
|
||||
Select Probe Hardware
|
||||
Select your adapter PRI port.
|
||||
|
||||
|
||||
5. Interface Section
|
||||
|
||||
Select number of interfaces you wish to configure
|
||||
(Default=1)
|
||||
|
||||
NOTE: Each network interface can be bound to 1 or ALL
|
||||
T1/E1 channels.
|
||||
|
||||
For each network interface do the following:
|
||||
|
||||
Specify interface name.
|
||||
(Leave it default)
|
||||
|
||||
Operation Mode:
|
||||
API used to develop custom applications
|
||||
on top of bitstreaming
|
||||
|
||||
WANPIPE used to run IP/PPP/CHDCL protocols
|
||||
on top of bitstreaming.
|
||||
|
||||
|
||||
HDLC Streaming:
|
||||
Option used to enable or disable HDLC engine.
|
||||
|
||||
YES: Enable HDLC engine which will encode and
|
||||
decode tx/rx packets into HDLC frames.
|
||||
|
||||
NO : Disable HDLC engine and pass the RAW
|
||||
bitstream up the stack, as well as tx
|
||||
unmodified user data.
|
||||
|
||||
|
||||
Bound T1/E1 Channels:
|
||||
(Only available on T1/E1 cards)
|
||||
|
||||
Bind any combination of T1/E1 channels to
|
||||
this interface.
|
||||
|
||||
Protocol:
|
||||
(Only available in WANPIPE operation mode)
|
||||
|
||||
Specify the upper layer protocol:
|
||||
RAW HDLC : Use raw IP protocol
|
||||
PPP : Run PPP protocol
|
||||
CHDLC : Run CHDLC protocol
|
||||
|
||||
Ignore Modem Status:
|
||||
(Only available in WANPIPE operation mode)
|
||||
|
||||
Option used to monitor the front end T1/E1
|
||||
status. If the front end looses sync the
|
||||
link will be declared down.
|
||||
|
||||
NO: Run front end monitoring (default)
|
||||
YES: Ignore front end state.
|
||||
|
||||
|
||||
IP Setup:
|
||||
(Only available in WANPIPE operation mode)
|
||||
|
||||
Specify IP info for network interface
|
||||
|
||||
6. End of configuration, exit and save
|
||||
|
||||
|
||||
|
||||
Start Bit Streaming protocol
|
||||
----------------------------
|
||||
|
||||
Run: wanrouter start
|
||||
|
||||
|
||||
In case of errors:
|
||||
------------------
|
||||
Run: wanrouter messages
|
||||
|
||||
It will display kernel error
|
||||
messages.
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
Startup Confirmation
|
||||
--------------------
|
||||
|
||||
Run: wanrouter messages
|
||||
|
||||
Make sure no error messages are dispalyed.
|
||||
|
||||
Confirm the state of Front End (T1/E1/V35)
|
||||
Confirm the Link state
|
||||
|
||||
Check for any error events.
|
||||
|
||||
|
||||
|
||||
Custom API Application
|
||||
----------------------
|
||||
|
||||
A sample API application exists in
|
||||
/etc/wanpipe/api/bitstrm directory.
|
||||
|
||||
To compile it run: make
|
||||
|
||||
Run: ./bitstrm_api
|
||||
|
||||
Refer to api options below:
|
||||
|
||||
BITSTRM API USAGE
|
||||
|
||||
|
||||
bitstrm_api <options> <extra options>
|
||||
|
||||
<options>:
|
||||
-i <ifname> #interface name
|
||||
-c <card name> #card name
|
||||
-r #read enable
|
||||
-w #write eable
|
||||
|
||||
<extra options>
|
||||
-txcnt <digit> #number of tx packets (Dflt: 1)
|
||||
-txsize <digit> #tx packet size (Dflt: 10)
|
||||
-txdelay <digit> #delay in sec after each tx packet (Dflt: 0)
|
||||
-txdata <digit> #data to tx <1-255>
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
#Enable read and write on wp1bistsrm1 interface
|
||||
|
||||
./bitstrm_api -c wanpipe1 -i wp1bistsrm1 -r -w
|
||||
|
||||
Use this app as a building block for you custom
|
||||
APP.
|
||||
|
||||
|
||||
|
||||
Further Info
|
||||
------------
|
||||
|
||||
Please contact Sangoma Tech Support
|
||||
Tel. 905 474 1990 ex118
|
||||
Email: techdesk@sangoma.com
|
||||
|
||||
|
||||
|
||||
|
||||
APPENDIX A: Bitstrm Switching
|
||||
=============================
|
||||
|
||||
|
||||
|
||||
3 ---------------- 1
|
||||
TE1/V35/RS232 |
|
||||
| TE1/Serial Kernel Driver Switch
|
||||
|
|
||||
4 ---------------- 2
|
||||
TE1/V35/RS232
|
||||
|
||||
|
||||
|
||||
Machine Config File
|
||||
|
||||
1 wanpipe1.conf
|
||||
2 wanpipe2.conf
|
||||
3 wanpipe3.conf
|
||||
4 wanpipe4.conf
|
||||
|
||||
|
||||
Wanpipes 1 and 2 have internal
|
||||
clocking.
|
||||
|
||||
Wanpipes 3 and 4 have external
|
||||
clocking.
|
||||
|
||||
|
||||
Important Switch Config Issues
|
||||
-------------------------------
|
||||
|
||||
The following variables are
|
||||
citical:
|
||||
|
||||
rx_sync_char = 0x7E
|
||||
monosync_tx_time_fill_char = 0x7E
|
||||
|
||||
max_length_tx_data_block = 500
|
||||
rx_complete_length = 500
|
||||
|
||||
|
||||
rx_sync_char:
|
||||
|
||||
Character used by bitsreaming
|
||||
receiver to sync up serial stream.
|
||||
Should be identical to
|
||||
monosync_tx_time_fill_char.
|
||||
|
||||
|
||||
monosync_tx_time_fill_char:
|
||||
|
||||
Character used by bitstreaming
|
||||
transmitter to idle flags.
|
||||
Should be identical to rx_sync_char
|
||||
|
||||
|
||||
max_length_tx_data_block:
|
||||
|
||||
Maximum tx size used by the
|
||||
bitstreaming transmitter.
|
||||
|
||||
This value should adjust to the
|
||||
BAUD rate used!
|
||||
|
||||
64Kbps = 120 bytes
|
||||
1.5Mbps = 1200 bytes
|
||||
|
||||
This value will determine the
|
||||
tx LATENCY from machine 3 to machine
|
||||
4.
|
||||
|
||||
It will also lower of increase
|
||||
number of interrupts.
|
||||
|
||||
rx_complete_length
|
||||
|
||||
Maximum rx size used by the
|
||||
bitstreaming tramsmitter.
|
||||
|
||||
This value should adjust to the
|
||||
BAUD rate used!
|
||||
|
||||
64Kbps = 120 bytes
|
||||
1.5Mbps = 1200 bytes
|
||||
|
||||
This value will determine the
|
||||
rx LATENCY from machine 3 to machine
|
||||
4.
|
||||
|
||||
It will also lower of increase
|
||||
number of interrupts.
|
||||
|
||||
NOTE: For both SWITCH wanipe1 and wanpipe2
|
||||
the above parameters should be IDENTICAL.
|
||||
|
||||
|
||||
HDLC Monitor
|
||||
------------
|
||||
|
||||
The hdlc monitor running over
|
||||
the bitstrm SWITCH
|
||||
|
||||
/etc/wanpipe/api/bistrm/datascope/ss7_monitor_api
|
||||
|
||||
To enable RAW hdlc use -prot 8
|
||||
|
||||
eg: ./ss7_monitor_api -i wp1bstrm1 -c wanpipe1 -r -prot 8 -verbose
|
||||
|
||||
|
||||
This will enable the hdlc monitoring over the
|
||||
bitstreaming switched interfaces.
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
|
||||
|
||||
|
||||
Ethernet Bridging over WANPIPE Frame Relay
|
||||
|
||||
|
||||
|
||||
Author: Nenad Corbic
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
November 20, 2000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Ethernet bridging over WANs all ows the Wide Area
|
||||
Network to operate as an exact analog of an ordinary Ethernet
|
||||
LAN. Traffic is not limited to IP, but any network protocol
|
||||
supported by Ethernet can be run transparently over a bridged
|
||||
WAN. These include IPX/SPX, AppleTalk and VINES. DHCP services
|
||||
can be used for IP management.
|
||||
|
||||
Bridging has particular application over one-to-many networks
|
||||
such as Frame Relay. ADSL networks often use a Frame Relay
|
||||
connection from the DSLAM to an ISP, with each DLCI supporting
|
||||
traffic from one DSL line. A Linux machine running bridged
|
||||
Ethernet over Frame Relay can provide a very attractive
|
||||
concentrator for such a system at the ISP end.
|
||||
|
||||
This implementation is based on work done by Mark Wells
|
||||
<mark@pc-intouch.com>, who did much of the original work
|
||||
on bridging for WANPIPE.
|
||||
|
||||
|
||||
Bridging over Frame Relay
|
||||
-------------------------
|
||||
|
||||
The Linux kernel contains the Ethernet bridging module
|
||||
that will be used to bridge the Frame Relay link to the Ethernet
|
||||
network. However, the Linux Bridge only supports Ethernet
|
||||
network interfaces, not Frame Relay: bridging is based on
|
||||
Ethernet MAC addresses.
|
||||
|
||||
|
||||
To interface WANPIPE Frame Relay network interfaces to the
|
||||
kernel bridge, it first must be reconfigured as an Ethernet
|
||||
network interface that will convert the Frame Relay header
|
||||
into the Ethernet header during data transmission. Thus,
|
||||
from the kernel point of view, WANPIPE Frame Relay links
|
||||
would behave like standard Ethernet connections.
|
||||
|
||||
Since the bridge works with MAC addresses, layer two of the
|
||||
OSI model, not IP, all interfaces that are directly connected
|
||||
to the bridge must not be configured for IP. This step has
|
||||
been automated using the wancfg configuration utility, by
|
||||
selecting the BRIDGE option in network interface setup.
|
||||
Thus, the Frame Relay network interface, configured for
|
||||
bridging would look as following, in the wanpipe#.conf
|
||||
configuration file.
|
||||
|
||||
Ex: [interfaces]
|
||||
wp1_fr16 = wanpipe1, 16, BRIDGE, comment
|
||||
|
||||
On the remote side of the Frame Relay link, WANPIPE network
|
||||
interfaces should be configured as BRIDGE_NODE(s).
|
||||
Since these interfaces will not be directly connected
|
||||
to the kernel bridge, they must be configured with IP
|
||||
addresses. The wancfg configuration utility will require
|
||||
the user to input IP addresses for each BRIDGE_NODE.
|
||||
|
||||
Note: if a DHCP server is used, set the BRIDGE_NODE IP
|
||||
address to a arbitrary value, since a DHCP client will
|
||||
override it when the interface activates.
|
||||
|
||||
|
||||
Configuring WANPIPE for bridging
|
||||
--------------------------------
|
||||
|
||||
To make the WANPIPE Frame Relay bridging easier
|
||||
to configure and install, WANPIPE configuration utility
|
||||
wancfg, and the wanrouter startup script will setup the
|
||||
virtual Ethernet interfaces according to the following
|
||||
options:
|
||||
|
||||
* If the WANPIPE network interfaces reside in the
|
||||
server where the kernel bridge is going to be implemented,
|
||||
then such interfaces should be configured as a BRIDGE.
|
||||
In this case, WANPIPE virtual Ethernet interface will
|
||||
be configured without IP information. Once the interface
|
||||
is started, the user must add the virtual interface
|
||||
(wp1fr16e) to the kernel bridge using the bridge
|
||||
configuration utility. Example of a BRIDGE interface
|
||||
is wpfr16e, in diagram below.
|
||||
|
||||
* If the WANPIPE network interface is located at the
|
||||
remote end of the bridge, meaning that the other side
|
||||
of the link is connected to a bridge, such interfaces
|
||||
should be configured as a BRIDGE_NODE.
|
||||
In this case, WANPIPE virtual Ethernet interface will
|
||||
be configured with IP information. Example of such
|
||||
interface is wp1fr16e, on diagram below.
|
||||
|
||||
|
||||
|
||||
|
||||
The BRIDGE Network Interface
|
||||
----------------------------
|
||||
|
||||
The WANPIPE virtual Ethernet network interfaces configured
|
||||
for BRIDGE operation mode are interfaces that directly connect to
|
||||
the Linux kernel bridge. Example of such interface is wpfr16e,
|
||||
in diagram above.
|
||||
|
||||
The WANPIPE configuration utility, wancfg, will setup the
|
||||
wanpipe#.conf configuration file for bridging. During startup,
|
||||
the wanrouter startup stcript will load the appropriate kernel
|
||||
modules and configure the virtual Ethernet network interfaces
|
||||
without IP information.
|
||||
|
||||
|
||||
The BRIDGE NODE Network Interface
|
||||
---------------------------------
|
||||
|
||||
The WANPIPE virtual Ethernet network interfaces configured as
|
||||
BRIDGE NODES are interfaces that are remotely connected to the
|
||||
Linux kernel bridge. Example of such interface is wp1fr16, in
|
||||
diagram above.
|
||||
|
||||
The WANPIPE configuration utility, wancfg, will setup the
|
||||
wanpipe#.conf configuration file for bridging. During startup,
|
||||
the wanrouter startup script will load the appropriate kernel
|
||||
modules and configure the virtual Ethernet network interfaces
|
||||
with IP information.
|
||||
|
||||
Since the bridge is on the remote end, no further
|
||||
configuration is needed. Assuming that the remote side has
|
||||
been successfully configured, the Remote Host would be able
|
||||
to ping the LAN.
|
||||
|
||||
|
||||
Example WANPIPE Bridge Configuration
|
||||
-------------------------------------
|
||||
|
||||
In this example we'll assume configuration as in diagram
|
||||
above. The configuration will be split into three parts:
|
||||
* Configuring the WANPIPE on the bridge,
|
||||
* Linux Kernel Bridge
|
||||
* WANPIPE remotely connected to the bridge.
|
||||
|
||||
This example assumes that WANPIPE drivers and utilities were
|
||||
installed properly on each system.
|
||||
|
||||
|
||||
Setting up Linux for Wanpipe and Bridging
|
||||
-----------------------------------------
|
||||
|
||||
* For WANPIPE installation instructions please
|
||||
refer to the WanpipeForLinux.pdf document.
|
||||
|
||||
* The WANPIPE setup utility will patch the new
|
||||
kernel with the latest WANPIPE drivers that
|
||||
include the WANPIPE bridging support.
|
||||
However, before recompiling the kernel, the
|
||||
Linux kernel must also be update with the latest
|
||||
bridging code.
|
||||
|
||||
* The latest bridging patches and utilities can be
|
||||
downloaded from http://projects.openrock.net/bridge/.
|
||||
|
||||
* The bridge patch should be applied to the kernel
|
||||
using the patch command
|
||||
|
||||
- copy the patch into the linux source
|
||||
directory /usr/src/linux
|
||||
|
||||
- patch the kernel : patch -p1 < patch_name.diff
|
||||
|
||||
* Once both the WANPIPE drivers and the kernel
|
||||
bridge have been updated proceed with WanpipdForLinux.pdf
|
||||
instructions on how to recompile the kernel.
|
||||
|
||||
|
||||
WANPIPE on the bridge server
|
||||
----------------------------
|
||||
|
||||
* Create the WANPIPE configuration file using the
|
||||
/usr/sbin/wacfg utility. The wancfg
|
||||
utility contains all the help files necessary to
|
||||
lead you through the protocol and hardware configuration.
|
||||
However, for each Frame Relay interface setup, the
|
||||
operation mode must be set to BRIDGE. Note: There will
|
||||
be no option for IP setup.
|
||||
|
||||
* Once the configuration file (wanpipe1.conf) is complete,
|
||||
start the WANPIPE device using the wanrouter start command.
|
||||
This command will load all necessary WANPIPE modules and
|
||||
setup all network interfaces. In this case all WANPIPE
|
||||
interfaces are configured without IP information.
|
||||
|
||||
wanrouter start
|
||||
|
||||
* Run ifconfig and confirm the encapsulation type of each
|
||||
Frame relay link configured.
|
||||
|
||||
Ifconfig
|
||||
|
||||
* Using the ifconfig command, set the eth0 IP address
|
||||
to 0.0.0.0 if not already done so.
|
||||
|
||||
ifconfig eth 0.0.0.0
|
||||
|
||||
|
||||
Linux Kernel Bridge
|
||||
-------------------
|
||||
|
||||
The Linux kernel bridge must be compiled, usually as a
|
||||
module, in the kernel. The bridging option can be selected from
|
||||
the Networking Option menu of the kernel configurator.
|
||||
|
||||
* Assuming the bridge support has been compiled as
|
||||
modules, proceed to load the kernel bridge as follows:
|
||||
|
||||
modprobe -v bridge
|
||||
|
||||
Note: If the bridge has been compiled directly into the kernel,
|
||||
this step is not necessary. However, if the module load
|
||||
fails, then the kernel has not been configured properly,
|
||||
please refer to the http://projects.openrock.net/bridge/
|
||||
for more information or check the kernel compilation.
|
||||
|
||||
* Use the brctrl utility to create a bridge and add network interfaces to it.
|
||||
(http://bridge.sourceforge.net/download.html)
|
||||
|
||||
Ex:
|
||||
Create the Bridge called "br0"
|
||||
brctl addbr br0
|
||||
|
||||
Add an interface into the bridge "br0"
|
||||
brctl addif br0 eth0
|
||||
brctl addif br0 wpfr16e
|
||||
brctl addif br0 wpfr17e
|
||||
brctl addif br0 wpfr18e
|
||||
|
||||
* Once all interfaces are added, make sure that eth0
|
||||
interface is not setup with IP addresses. If so, zero the
|
||||
eth0 IP addresses.
|
||||
|
||||
ifconfig eth0 0.0.0.0
|
||||
|
||||
* To add IP support to the bridge server, configure the
|
||||
bridge network interface br0 with appropriate IP addresses.
|
||||
|
||||
ifconfig br0 192.168.1.1 netmask 255.255.255.0 up
|
||||
|
||||
Since we cannot configure IP addresses to any network
|
||||
interfaces that are directly connected to the bridge,
|
||||
currently there is no way of accessing the bridge
|
||||
server itself using IP. Therefore, an IP address must
|
||||
be defined for the bridge itself. The kernel bridge
|
||||
has a special network interface that can be configured
|
||||
with IP. This network interface has the same name as
|
||||
the bridge; In the case above the interface name would
|
||||
be br0. Using the ifconfig() command an IP address must
|
||||
be manually applied to the bride network interface.
|
||||
|
||||
|
||||
WANPIPE Bridge Node
|
||||
-------------------
|
||||
|
||||
* Create the WANPIPE configuration file using the
|
||||
/usr/sbin/wacfg utility. The wancfg utility
|
||||
contains all the help files necessary to lead you through
|
||||
the protocol and hardware configuration. However, for each
|
||||
Frame Relay interface setup, the operation mode must be
|
||||
set to BRIDGE_NODE and IP information must be setup.
|
||||
|
||||
Note: When setting IP information, make sure that the
|
||||
IP network address is the same as the LAN network
|
||||
address. Bridge cannot connect two different networks.
|
||||
|
||||
* Once the configuration file (wanpipe1.conf) is complete,
|
||||
start the WANPIPE device using the wanrouter start command.
|
||||
This command will load all necessary WANPIPE modules and
|
||||
setup all network interfaces. In this case all WANPIPE
|
||||
interfaces are configured without IP information.
|
||||
|
||||
wanrouter start
|
||||
|
||||
Note: if a DHCP server is used, set the BRIDGE_NODE IP
|
||||
address to a arbitrary value, since a DHCP client
|
||||
will override it when the interface activates.
|
||||
|
||||
Assuming that the other end has been configured,
|
||||
one should be able to ping the remote LAN.
|
|
@ -0,0 +1,140 @@
|
|||
WANROUTER Support for External Scritps
|
||||
======================================
|
||||
|
||||
|
||||
At the heart of WANPIPE operation is the 'wanrouter' operation
|
||||
script. It is used to start/stop/restart and display
|
||||
WANPIPE current status and environment.
|
||||
|
||||
|
||||
'wanrouter' usage
|
||||
=================
|
||||
|
||||
/usr/sbin/wanrouter <cr>
|
||||
|
||||
|
||||
WANPIPE: WAN Router startup script
|
||||
|
||||
Usage: wanrouter: {options} <wanpipe#> <interface>
|
||||
|
||||
wanrouter start : Starts all devices specified in
|
||||
/etc/wanpipe/wanrouter.rc WAN_DEVICES
|
||||
|
||||
wanrouter stop : Stops all devices specified in
|
||||
/etc/wanpipe/wanrouter.rc WAN_DEVICES
|
||||
|
||||
wanrouter start wanpipe# : Start a single device
|
||||
|
||||
wanrouter stop wanpipe# : Stops a single device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
wanrouter restart : Restart all devices specified in
|
||||
/etc/wanpipe/wanrouter.rc WAN_DEVICES
|
||||
|
||||
wanrouter restart wanpipe# : Restart a single device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
|
||||
wanrouter start wanpipe# if_name : Start a single interface on device
|
||||
|
||||
wanrouter stop wanpipe# if_name : Stops a single interface on device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
wanrouter restart wanpipe# if_name : Restart a single interface on device
|
||||
(# can range from 1 to 16)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
External Scripts
|
||||
================
|
||||
|
||||
The wanrouter utility will also EXECUTE any external
|
||||
script that is located in /etc/wanpipe/scripts directory.
|
||||
Furthermore wanrouter utility will execute number of
|
||||
scripts depending on what is being started or stopped.
|
||||
|
||||
Global Start/Stop Script
|
||||
------------------------
|
||||
|
||||
Global Start : wanrouter start
|
||||
Global Stop : wanrouter stop
|
||||
Global Restart: wanrouter restart
|
||||
|
||||
Script Location: /etc/wanpipe/scripts
|
||||
|
||||
Start Script Name: start
|
||||
|
||||
Script "start" will execute after a sucessfull
|
||||
"wanrouter start" command. The wanrouter start
|
||||
command will start one or more configured
|
||||
wanpipe devices.
|
||||
|
||||
Stop Script Name : stop
|
||||
|
||||
Script "stop" will execute after a sucessfull
|
||||
"wanrouter stop" command. The wanrouter stop
|
||||
command will stop one or more configured
|
||||
wanpipe devices.
|
||||
|
||||
|
||||
Device Start/Stop Script
|
||||
------------------------
|
||||
|
||||
Device start : wanrouter start wanpipe1
|
||||
Device stop : wanrouter stop wanpipe1
|
||||
Device restart: wanrouter restart wanpipe1
|
||||
|
||||
Script Location: /etc/wanpipe/scripts
|
||||
|
||||
Start Script Name: wanpipe#-start Where #={1,2,3,4...}
|
||||
|
||||
Script "wanpipe1-start" will execute after:
|
||||
Device Start
|
||||
Global Start (if wanpipe1 is part of the start list)
|
||||
|
||||
Stop Script Name : wanpipe#-stop Where #={1,2,3,4...}
|
||||
|
||||
Script "wanpipe1-stop" will execute after:
|
||||
Device Stop
|
||||
Global Stop (if wanpipe1 is part of the start list)
|
||||
|
||||
|
||||
Interface Start/Stop Script
|
||||
---------------------------
|
||||
|
||||
Interface start : wanrouter start wanpipe1 w1g1
|
||||
Interface stop : wanrouter stop wanpipe1 w1g1
|
||||
Interface restart: wanrouter restart wanpipe1 w1g1
|
||||
|
||||
Script Location: /etc/wanpipe/scripts
|
||||
|
||||
Start Script Name: wanpipe1-w1g1-start
|
||||
|
||||
Script "wanpipe1-start-w1g1" will execute after:
|
||||
Interface Start
|
||||
Device Start
|
||||
Global Start (if wanpipe1 is part of the start list)
|
||||
|
||||
Start Script Name: wanpipe1-w1g1-stop
|
||||
|
||||
Script "wanpipe1-stop-w1g1" will execute after:
|
||||
Interface Stop
|
||||
Device Stop
|
||||
Global Stop (if wanpipe1 is part of the start list)
|
||||
|
||||
|
||||
The bash script should be written as follows:
|
||||
|
||||
----------CUT----------------
|
||||
#!/bin/sh
|
||||
|
||||
#Put shell script commands here
|
||||
|
||||
|
||||
|
||||
|
||||
----------CUT-----------------
|
||||
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
Wanpipe FAQ
|
||||
===========
|
||||
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
|
||||
1. Wanpipe is connected to a remote cisco router via
|
||||
Frame Relay. The problem is that Pings work, but
|
||||
HTTP and DNS requests fail?
|
||||
|
||||
2. Running Zebra OSPF over WANPIPE, produces
|
||||
inactive routes?
|
||||
|
||||
3. How to enable ip_forwarding on RedHat 8.0
|
||||
|
||||
4. How to loadbalance multiple T1/E1/56K Wanpipe lines?
|
||||
|
||||
5. How to bind an irq to a single or multiple CPUs?
|
||||
|
||||
6. Wanpipe interfaces don't come up, on wanrouter start ?
|
||||
|
||||
|
||||
|
||||
1.----------------------------------------------------
|
||||
|
||||
|
||||
Q: Wanpipe is connected to a remote cisco router via
|
||||
Frame Relay. The problem is that Pings work, but
|
||||
HTTP and DNS requests fail?
|
||||
|
||||
A: Make sure that Frame-Relay payload compression is
|
||||
OFF on the Cisco Router.
|
||||
|
||||
2.------------------------------------------------------
|
||||
|
||||
Q: Running Zebra OSPF over WANPIPE.
|
||||
When I start zebra, OSPF has inactive routes
|
||||
|
||||
A: If OSPF comes back with inactive routes, problem
|
||||
lies with the wanpipe netmask address.
|
||||
|
||||
Netmask address has to be set to
|
||||
255.255.255.255 for pointopoint links.
|
||||
|
||||
|
||||
3.------------------------------------------------------
|
||||
|
||||
Q: How to enable ip_forwarding on RedHat 8.0
|
||||
|
||||
A: Edit /etc/sysctl.conf
|
||||
|
||||
To enable ip forwarding on boot up set variable
|
||||
net.ipv4.ip_forward to 1.
|
||||
|
||||
net.ipv4.ip_forward = 1
|
||||
|
||||
|
||||
4.------------------------------------------------------
|
||||
|
||||
Q: How to loadbalance multiple T1/E1/56K Wanpipe lines?
|
||||
|
||||
|
||||
A: Linux offers numberous ways to loadbalance
|
||||
multiple WAN lines.
|
||||
|
||||
Available Options: TEQL, PPP Multilink, IPROUTE2
|
||||
|
||||
TEQL: Round robin packet equalization between
|
||||
multiple links.
|
||||
|
||||
Refer to README.loadbalancing
|
||||
|
||||
PPP MULTILINK: True loadbalancing protocol. However,
|
||||
MULITLINK protocol must be supported
|
||||
by both sides of the link.
|
||||
|
||||
Refer to README.multilink
|
||||
|
||||
IPROUTE2: Equal Cost Multi-Path routing
|
||||
Attach weights to each path, usefull when two
|
||||
lines are not the same baud rate.
|
||||
|
||||
|
||||
|
||||
5.------------------------------------------------------
|
||||
|
||||
Q: How to bind an irq to a single or multiple CPUs?
|
||||
|
||||
A: Refer to README.irq_to_cpu_smp_mapping
|
||||
|
||||
|
||||
6.--------------------------------------------------------
|
||||
|
||||
Problem: HOTPLUG
|
||||
|
||||
The hotplug driver, automatically starts up the
|
||||
interface and then brings it down. This conflicts
|
||||
with our driver.
|
||||
|
||||
Possible Solutions:
|
||||
|
||||
1) Remove the Hotplug RPM
|
||||
rpm -qa | grep hotplug
|
||||
rpm -e <hotplug name>
|
||||
|
||||
2) Stop hotplug:
|
||||
/etc/init.d/hotplug stop
|
||||
|
||||
However, you must do this each
|
||||
time you boot up.
|
||||
|
||||
3) Insert wanpipe interface name into the hotplug
|
||||
interface list, and restart hotplug.
|
||||
|
||||
vi /etc/hotplug/net.agent
|
||||
|
||||
Insert wanpipe interface name into
|
||||
the ignore list:
|
||||
|
||||
...ppp*|lo*|w*)
|
||||
|
||||
Where w* relates to all wanpipe interfaces
|
||||
starting with letter "w"
|
||||
|
||||
Restart hotplug agent:
|
||||
|
||||
/etc/init.d/hotplug restart
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue